Enable CL image processor via xcamsrc plugin

Image processor and 3A analyzer can be configured via set_property.
Restructure MainDeviceManager to reuse more from DeviceManager.
gstxcamsrc can handle both drm bo buffer and v4l2 buffer now.
diff --git a/wrapper/gstreamer/bufmap.h b/wrapper/gstreamer/bufmap.h
index 5db811d..7a25899 100644
--- a/wrapper/gstreamer/bufmap.h
+++ b/wrapper/gstreamer/bufmap.h
@@ -21,11 +21,13 @@
 #ifndef __BUFMAP_H__
 #define __BUFMAP_H__
 
+#include <assert.h>
 #include <gst/gst.h>
 #include <map>
 #include "xcam_defs.h"
-#include "v4l2_buffer_proxy.h"
-#include "atomisp_device.h"
+#include "smartptr.h"
+#include "xcam_mutex.h"
+#include "video_buffer.h"
 
 namespace XCam {
 
@@ -33,22 +35,21 @@
 public:
     static SmartPtr<BufMap> instance();
 
-    GstBuffer* gbuf(SmartPtr<V4l2BufferProxy> &buf) {
-        uint32_t vbuf_idx = buf->get_v4l2_buf_index();
-        if (_v2g.find(vbuf_idx) == _v2g.end()) { //non-existing
+    GstBuffer* gbuf(SmartPtr<VideoBuffer> &buf) {
+        if (_v2g.find (buf.ptr ()) == _v2g.end ()) { //non-existing
             return NULL;
         }
-        return _v2g[vbuf_idx];
+        return _v2g[buf.ptr ()];
     }
-    SmartPtr<V4l2BufferProxy> vbuf(GstBuffer* gbuf) {
-        if (_g2v.find(gbuf) == _g2v.end()) { //non-existing
+    SmartPtr<VideoBuffer> vbuf(GstBuffer* gbuf) {
+        if (_g2v.find (gbuf) == _g2v.end ()) { //non-existing
             return NULL;
         }
         return _g2v[gbuf];
     }
-    void setmap(GstBuffer* gbuf, SmartPtr<V4l2BufferProxy>& buf) {
-        //_g2v[gbuf] = buf;
-        _v2g[buf->get_v4l2_buf_index()] = gbuf;
+    void setmap(GstBuffer* gbuf, SmartPtr<VideoBuffer>& buf) {
+        _g2v[gbuf] = buf.ptr ();
+        _v2g[buf.ptr ()] = gbuf;
     }
 
 private:
@@ -60,8 +61,8 @@
     static SmartPtr<BufMap> _instance;
     static Mutex        _mutex;
 
-    std::map <GstBuffer*, SmartPtr<V4l2BufferProxy> > _g2v;
-    std::map <uint32_t, GstBuffer*> _v2g;
+    std::map <GstBuffer*, VideoBuffer*> _g2v;
+    std::map <VideoBuffer*, GstBuffer*> _v2g;
 };
 
 } //namespace
diff --git a/wrapper/gstreamer/gstxcamsrc.cpp b/wrapper/gstreamer/gstxcamsrc.cpp
index db6a4f7..df14c48 100644
--- a/wrapper/gstreamer/gstxcamsrc.cpp
+++ b/wrapper/gstreamer/gstxcamsrc.cpp
@@ -61,6 +61,45 @@
 GST_DEBUG_CATEGORY_STATIC (gst_xcamsrc_debug);
 #define GST_CAT_DEFAULT gst_xcamsrc_debug
 
+#define GST_TYPE_XCAM_SRC_IMAGE_PROCESSOR (gst_xcam_src_image_processor_get_type ())
+static GType
+gst_xcam_src_image_processor_get_type (void)
+{
+    static GType g_type = 0;
+    static const GEnumValue image_processor_types[] = {
+        {ISP_IMAGE_PROCESSOR, "ISP image processor", "isp"},
+        {CL_IMAGE_PROCESSOR, "CL image processor", "cl"},
+        {0, NULL, NULL},
+    };
+
+    if (g_once_init_enter (&g_type)) {
+        const GType type =
+            g_enum_register_static ("GstXcamSrcImageProcessor", image_processor_types);
+        g_once_init_leave (&g_type, type);
+    }
+
+    return g_type;
+}
+
+#define GST_TYPE_XCAM_SRC_ANALYZER (gst_xcam_src_analyzer_get_type ())
+static GType
+gst_xcam_src_analyzer_get_type (void)
+{
+    static GType g_type = 0;
+    static const GEnumValue analyzer_types[] = {
+        {SIMPLE_ANALYZER, "simple 3A analyzer", "simple"},
+        {AIQ_ANALYZER, "aiq 3A analyzer", "aiq"},
+        {0, NULL, NULL},
+    };
+
+    if (g_once_init_enter (&g_type)) {
+        const GType type =
+            g_enum_register_static ("GstXcamSrcAnalyzer", analyzer_types);
+        g_once_init_leave (&g_type, type);
+    }
+
+    return g_type;
+}
 
 enum
 {
@@ -78,7 +117,9 @@
     PROP_HEIGHT,
     PROP_PIXELFORMAT,
     PROP_FIELD,
-    PROP_BYTESPERLINE
+    PROP_BYTESPERLINE,
+    PROP_IMAGE_PROCESSOR,
+    PROP_3A_ANALYZER
 };
 
 static void gst_xcamsrc_xcam_3a_interface_init (GstXCam3AInterface *iface);
@@ -167,6 +208,14 @@
     g_object_class_install_property (gobject_class, PROP_BYTESPERLINE,
                                      g_param_spec_int ("bytesperline", "bytes perline", "bytes perline",
                                              0, G_MAXINT, DEFAULT_PROP_BYTESPERLINE, (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS) ));
+    g_object_class_install_property (gobject_class, PROP_IMAGE_PROCESSOR,
+                                     g_param_spec_enum ("imageprocessor", "image processor", "image processor",
+                                             GST_TYPE_XCAM_SRC_IMAGE_PROCESSOR, ISP_IMAGE_PROCESSOR,
+                                             (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+    g_object_class_install_property (gobject_class, PROP_3A_ANALYZER,
+                                     g_param_spec_enum ("analyzer", "3a analyzer", "3a analyzer",
+                                             GST_TYPE_XCAM_SRC_ANALYZER, SIMPLE_ANALYZER,
+                                             (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
 
     gst_element_class_set_details_simple(element_class,
                                          "Libxcam Source",
@@ -190,10 +239,6 @@
 static void
 gst_xcamsrc_init (Gstxcamsrc *xcamsrc)
 {
-    MainDeviceManager::set_capture_device_name (DEFAULT_CAPTURE_DEVICE);
-    MainDeviceManager::set_event_device_name (DEFAULT_EVENT_DEVICE);
-    MainDeviceManager::set_cpf_file_name (DEFAULT_CPF_FILE_NAME);
-
     gst_base_src_set_format (GST_BASE_SRC (xcamsrc), GST_FORMAT_TIME);
     gst_base_src_set_live (GST_BASE_SRC (xcamsrc), TRUE);
 
@@ -202,9 +247,11 @@
     xcamsrc->_fps_d = DEFAULT_PROP_FPSD; //1
     xcamsrc->width = DEFAULT_PROP_WIDTH; //1920
     xcamsrc->height = DEFAULT_PROP_HEIGHT; //1080
-    xcamsrc->pixelformat = V4L2_PIX_FMT_NV12; //420
+    xcamsrc->pixelformat = V4L2_PIX_FMT_NV12;
     xcamsrc->field = V4L2_FIELD_NONE; //0
     xcamsrc->bytes_perline = DEFAULT_PROP_BYTESPERLINE; // 3840
+    xcamsrc->image_processor_type = ISP_IMAGE_PROCESSOR;
+    xcamsrc->analyzer_type = SIMPLE_ANALYZER;
 
     gst_base_src_set_blocksize (GST_BASE_SRC (xcamsrc), DEFAULT_BLOCKSIZE);
 }
@@ -226,27 +273,62 @@
     gst_object_sync_values (GST_OBJECT (src), xcamsrc->ctrl_time);
 
     SmartPtr<MainDeviceManager> device_manager = DeviceManagerInstance::device_manager_instance();
-    SmartPtr<V4l2Device> device = device_manager->get_device();
-    SmartPtr<V4l2SubDevice> sub_device = device_manager->get_sub_device();
 
-    /**
-     * set_sensor_id
-     * set_capture_mode
-     * set_mem_type
-     * set_buffer_count
-     * set_framerate
-     * open
-     * set_format
-     *
-     **/
-    device->set_buffer_count (xcamsrc->buf_count);
-    device->set_framerate (xcamsrc->_fps_n, xcamsrc->_fps_d);
-    device->open ();
-    device->set_format  (xcamsrc->width, xcamsrc->height, xcamsrc->pixelformat, xcamsrc->field, xcamsrc->bytes_perline);
+    SmartPtr<V4l2Device> capture_device;
+    if (xcamsrc->capture_mode == V4L2_CAPTURE_MODE_STILL)
+        capture_device = new AtomispDevice (CAPTURE_DEVICE_STILL);
+    else
+        capture_device = new AtomispDevice (CAPTURE_DEVICE_VIDEO);
+    device_manager->set_capture_device (capture_device);
+    capture_device->set_sensor_id (xcamsrc->sensor_id);
+    capture_device->set_capture_mode (xcamsrc->capture_mode);
+    capture_device->set_mem_type (xcamsrc->mem_type);
+    capture_device->set_buffer_count (xcamsrc->buf_count);
+    capture_device->set_framerate (xcamsrc->_fps_n, xcamsrc->_fps_d);
+    capture_device->open ();
+    capture_device->set_format (xcamsrc->width, xcamsrc->height, xcamsrc->pixelformat, xcamsrc->field, xcamsrc->bytes_perline);
 
-    sub_device->open();
-    sub_device->subscribe_event (V4L2_EVENT_ATOMISP_3A_STATS_READY);
-    sub_device->subscribe_event (V4L2_EVENT_FRAME_SYNC);
+    SmartPtr<V4l2SubDevice> event_device = new V4l2SubDevice (DEFAULT_EVENT_DEVICE);
+    device_manager->set_event_device (event_device);
+    event_device->open ();
+    event_device->subscribe_event (V4L2_EVENT_ATOMISP_3A_STATS_READY);
+    event_device->subscribe_event (V4L2_EVENT_FRAME_SYNC);
+
+    SmartPtr<IspController> isp_controller = new IspController (capture_device);
+    device_manager->set_isp_controller (isp_controller);
+
+    SmartPtr<ImageProcessor> isp_processor;
+#if HAVE_LIBCL
+    SmartPtr<CL3aImageProcessor> cl_processor = new CL3aImageProcessor ();
+#endif
+    switch (xcamsrc->image_processor_type) {
+#if HAVE_LIBCL
+    case CL_IMAGE_PROCESSOR:
+        isp_processor = new IspExposureImageProcessor (isp_controller);
+        XCAM_ASSERT (isp_processor.ptr ());
+        device_manager->add_image_processor (isp_processor);
+        cl_processor = new CL3aImageProcessor ();
+        cl_processor->set_stats_callback (device_manager);
+        device_manager->add_image_processor (cl_processor);
+        break;
+#endif
+    default:
+        isp_processor = new IspImageProcessor (isp_controller);
+        device_manager->add_image_processor (isp_processor);
+    }
+
+    SmartPtr<X3aAnalyzer> analyzer;
+    switch (xcamsrc->analyzer_type) {
+#if HAVE_IA_AIQ
+    case AIQ_ANALYZER:
+        analyzer = new X3aAnalyzerAiq (isp_controller, DEFAULT_CPF_FILE_NAME);
+        break;
+#endif
+    default:
+        analyzer = new X3aAnalyzerSimple ();
+    }
+    device_manager->set_analyzer (analyzer);
+
     device_manager->start ();
 
     return TRUE;
@@ -259,8 +341,8 @@
     SmartPtr<MainDeviceManager> device_manager = DeviceManagerInstance::device_manager_instance();
 
     device_manager->stop();
-    device_manager->get_device()->close ();
-    device_manager->get_sub_device()->close ();
+    device_manager->get_capture_device()->close ();
+    device_manager->get_event_device()->close ();
     return TRUE;
 }
 
@@ -281,7 +363,7 @@
 
     guint32 block_size = DEFAULT_BLOCKSIZE;
     SmartPtr<MainDeviceManager> device_manager = DeviceManagerInstance::device_manager_instance();
-    SmartPtr<V4l2Device> device = device_manager->get_device();
+    SmartPtr<V4l2Device> device = device_manager->get_capture_device();
 
 
     struct v4l2_format format;
@@ -297,8 +379,6 @@
     return TRUE;
 }
 
-
-
 static GstFlowReturn gst_xcamsrc_alloc (GstBaseSrc *src, guint64 offset, guint size, GstBuffer **buffer)
 {
     GstFlowReturn ret;
@@ -402,7 +482,6 @@
     Gstxcamsrc *src = GST_XCAMSRC (object);
     int val;
     enum v4l2_memory set_val;
-    SmartPtr<V4l2Device> device = DeviceManagerInstance::device_manager_instance()->get_device();
 
     switch (prop_id) {
     case PROP_DEVICE:
@@ -410,23 +489,42 @@
     case PROP_COLOREFFECT:
         break;
     case PROP_SENSOR:
-        device->set_sensor_id (g_value_get_int (value));
+        src->sensor_id = g_value_get_int (value);
         break;
     case PROP_CAPTURE_MODE:
-        val = g_value_get_int (value);
-        device->set_capture_mode (1 << (13 + val));
+        switch (g_value_get_int (value)) {
+        case 0:
+            src->capture_mode = V4L2_CAPTURE_MODE_STILL;
+            break;
+        case 1:
+            src->capture_mode = V4L2_CAPTURE_MODE_VIDEO;
+            break;
+        case 2:
+            src->capture_mode = V4L2_CAPTURE_MODE_PREVIEW;
+            break;
+        default:
+            XCAM_LOG_ERROR ("Invalid capure mode");
+            break;
+        }
         break;
     case PROP_IO_MODE:
-        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;
-        device->set_mem_type (set_val);
+        switch (g_value_get_int (value)) {
+        case 1:
+            src->mem_type = V4L2_MEMORY_MMAP;
+            break;
+        case 2:
+            src->mem_type = V4L2_MEMORY_USERPTR;
+            break;
+        case 3:
+            src->mem_type = V4L2_MEMORY_OVERLAY;
+            break;
+        case 4:
+            src->mem_type = V4L2_MEMORY_DMABUF;
+            break;
+        default:
+            XCAM_LOG_ERROR ("Invalid io mode");
+            break;
+        }
         break;
     case PROP_BUFFERCOUNT:
         src->buf_count = g_value_get_int (value);
@@ -454,6 +552,20 @@
     case PROP_BYTESPERLINE:
         src->bytes_perline = g_value_get_int (value);
         break;
+    case PROP_IMAGE_PROCESSOR:
+        src->image_processor_type = (ImageProcessorType)g_value_get_enum (value);
+        if (src->image_processor_type == ISP_IMAGE_PROCESSOR) {
+            src->capture_mode = V4L2_CAPTURE_MODE_VIDEO;
+            src->pixelformat = V4L2_PIX_FMT_NV12;
+        }
+        else if (src->image_processor_type == CL_IMAGE_PROCESSOR) {
+            src->capture_mode = V4L2_CAPTURE_MODE_STILL;
+            src->pixelformat = V4L2_PIX_FMT_SGRBG10;
+        }
+        break;
+    case PROP_3A_ANALYZER:
+        src->analyzer_type = (AnalyzerType)g_value_get_enum (value);
+        break;
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
         break;
diff --git a/wrapper/gstreamer/gstxcamsrc.h b/wrapper/gstreamer/gstxcamsrc.h
index de732cb..38d96ee 100644
--- a/wrapper/gstreamer/gstxcamsrc.h
+++ b/wrapper/gstreamer/gstxcamsrc.h
@@ -27,7 +27,8 @@
 #include <xcam_defs.h>
 
 #define DEFAULT_BLOCKSIZE   1843200
-#define DEFAULT_CAPTURE_DEVICE  "/dev/video3"
+#define CAPTURE_DEVICE_STILL  "/dev/video0"
+#define CAPTURE_DEVICE_VIDEO  "/dev/video3"
 #define DEFAULT_EVENT_DEVICE    "/dev/v4l-subdev6"
 #define DEFAULT_CPF_FILE_NAME   "/etc/atomisp/imx185.cpf"
 
@@ -44,6 +45,10 @@
 #define DEFAULT_PROP_FIELD      V4L2_FIELD_NONE // 0
 #define DEFAULT_PROP_BYTESPERLINE   3840
 
+#define V4L2_CAPTURE_MODE_STILL 0x2000
+#define V4L2_CAPTURE_MODE_VIDEO 0x4000
+#define V4L2_CAPTURE_MODE_PREVIEW 0x8000
+
 G_BEGIN_DECLS
 
 /* #defines don't like whitespacey bits */
@@ -59,6 +64,16 @@
   (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_XCAMSRC))
 #define GST_XCAMSRC_CAST(obj)   ((Gstxcamsrc *) obj)
 
+typedef enum {
+    ISP_IMAGE_PROCESSOR = 0,
+    CL_IMAGE_PROCESSOR,
+} ImageProcessorType;
+
+typedef enum {
+    SIMPLE_ANALYZER = 0,
+    AIQ_ANALYZER,
+} AnalyzerType;
+
 typedef struct _Gstxcamsrc      Gstxcamsrc;
 typedef struct _GstxcamsrcClass GstxcamsrcClass;
 
@@ -78,6 +93,11 @@
     guint pixelformat;
     enum v4l2_field field;
     guint bytes_perline;
+    gint sensor_id;
+    guint capture_mode;
+    enum v4l2_memory mem_type;
+    ImageProcessorType image_processor_type;
+    AnalyzerType analyzer_type;
 
     GstClockTime duration;
     GstClockTime ctrl_time;
diff --git a/wrapper/gstreamer/stub.cpp b/wrapper/gstreamer/stub.cpp
index 2f88a60..39bdb8d 100644
--- a/wrapper/gstreamer/stub.cpp
+++ b/wrapper/gstreamer/stub.cpp
@@ -21,28 +21,26 @@
 #include "stub.h"
 #include "bufmap.h"
 #include "v4l2dev.h"
-
+#include "drm_bo_buffer.h"
 #include <stdio.h>
 
 using namespace XCam;
 
-int libxcam_dequeue_buffer (SmartPtr<V4l2BufferProxy> &buf)
+int libxcam_dequeue_buffer (SmartPtr<VideoBuffer> &buf)
 {
     SmartPtr<MainDeviceManager> device_manager = DeviceManagerInstance::device_manager_instance();
     int ret;
-    SmartPtr<VideoBuffer> video_buffer;
 
     pthread_mutex_lock (&device_manager->bufs_mutex);
     if (device_manager->bufs.size() == 0) {
         pthread_cond_wait (&device_manager->bufs_cond, &device_manager->bufs_mutex);
     }
-    video_buffer = device_manager->bufs.front();
+    buf = device_manager->bufs.front();
     device_manager->bufs.pop();
     pthread_mutex_unlock (&device_manager->bufs_mutex);
-    buf = video_buffer.dynamic_cast_ptr<V4l2BufferProxy>();
 
     pthread_mutex_lock (&device_manager->release_mutex);
-    device_manager->release_bufs.push (video_buffer);
+    device_manager->release_bufs.push (buf);
     pthread_mutex_unlock (&device_manager->release_mutex);
     return (int) XCAM_RETURN_NO_ERROR;
 }
@@ -54,19 +52,23 @@
     Gstxcambufferpool *pool = GST_XCAMBUFFERPOOL_CAST (bpool);
     Gstxcamsrc *xcamsrc = pool->src;
 
-    SmartPtr<V4l2BufferProxy> buf;
+    SmartPtr<VideoBuffer> buf;
     libxcam_dequeue_buffer (buf);
 
-    SmartPtr<BufMap> bufmap = BufMap::instance();
-    gbuf = bufmap->gbuf(buf);
+    SmartPtr<BufMap> bufmap = BufMap::instance ();
+    gbuf = bufmap->gbuf (buf);
 
     if (!gbuf) {
         gbuf = gst_buffer_new();
-        GST_BUFFER (gbuf)->pool = (GstBufferPool*) pool;
+        GST_BUFFER (gbuf)->pool = (GstBufferPool *) pool;
 
         gst_buffer_append_memory (gbuf,
-                                  gst_dmabuf_allocator_alloc (pool->allocator, buf->get_v4l2_dma_fd(), buf->get_v4l2_buf_length()));
-        bufmap->setmap(gbuf, buf);
+                                  gst_dmabuf_allocator_alloc (pool->allocator,
+                                          buf->get_fd (),
+                                          buf->get_size ()));
+        bufmap->setmap (gbuf, buf);
+        XCAM_LOG_DEBUG ("%s new gst-buf: fd(%d), size(%d)",
+                        __func__, buf->get_fd (), buf->get_size ());
     }
 
     GST_BUFFER_TIMESTAMP (gbuf) = buf->get_timestamp();
@@ -87,190 +89,190 @@
 gboolean gst_xcamsrc_set_white_balance_mode (GstXCam3A *xcam3a, XCamAwbMode mode)
 {
     SmartPtr<MainDeviceManager> device_manager = DeviceManagerInstance::device_manager_instance();
-    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_x3a_analyzer ();
+    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_analyzer ();
     return analyzer->set_awb_mode (mode);
 }
 
 gboolean gst_xcamsrc_set_awb_speed (GstXCam3A *xcam3a, double speed)
 {
     SmartPtr<MainDeviceManager> device_manager = DeviceManagerInstance::device_manager_instance();
-    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_x3a_analyzer ();
+    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_analyzer ();
     return analyzer->set_awb_speed (speed);
 }
 
 gboolean gst_xcamsrc_set_wb_color_temperature_range (GstXCam3A *xcam3a, guint cct_min, guint cct_max)
 {
     SmartPtr<MainDeviceManager> device_manager = DeviceManagerInstance::device_manager_instance();
-    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_x3a_analyzer ();
+    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_analyzer ();
     return analyzer->set_awb_color_temperature_range (cct_min, cct_max);
 }
 gboolean gst_xcamsrc_set_manual_wb_gain (GstXCam3A *xcam3a, double gr, double r, double b, double gb)
 {
     SmartPtr<MainDeviceManager> device_manager = DeviceManagerInstance::device_manager_instance();
-    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_x3a_analyzer ();
+    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_analyzer ();
     return analyzer->set_awb_manual_gain (gr, r, b, gb);
 }
 gboolean gst_xcamsrc_set_exposure_mode (GstXCam3A *xcam3a, XCamAeMode mode)
 {
     SmartPtr<MainDeviceManager> device_manager = DeviceManagerInstance::device_manager_instance();
-    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_x3a_analyzer ();
+    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_analyzer ();
     return analyzer->set_ae_mode (mode);
 }
 
 gboolean gst_xcamsrc_set_ae_metering_mode (GstXCam3A *xcam3a, XCamAeMeteringMode mode)
 {
     SmartPtr<MainDeviceManager> device_manager = DeviceManagerInstance::device_manager_instance();
-    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_x3a_analyzer ();
+    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_analyzer ();
     return analyzer->set_ae_metering_mode (mode);
 }
 gboolean gst_xcamsrc_set_exposure_window (GstXCam3A *xcam3a, XCam3AWindow *window)
 {
     SmartPtr<MainDeviceManager> device_manager = DeviceManagerInstance::device_manager_instance();
-    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_x3a_analyzer ();
+    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_analyzer ();
     return analyzer->set_ae_window (window);
 }
 gboolean gst_xcamsrc_set_exposure_value_offset (GstXCam3A *xcam3a, double ev_offset)
 {
     SmartPtr<MainDeviceManager> device_manager = DeviceManagerInstance::device_manager_instance();
-    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_x3a_analyzer ();
+    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_analyzer ();
     return analyzer->set_ae_ev_shift (ev_offset);
 }
 gboolean gst_xcamsrc_set_ae_speed (GstXCam3A *xcam3a, double speed)
 {
     SmartPtr<MainDeviceManager> device_manager = DeviceManagerInstance::device_manager_instance();
-    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_x3a_analyzer ();
+    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_analyzer ();
     return analyzer->set_ae_speed (speed);
 }
 gboolean gst_xcamsrc_set_exposure_flicker_mode (GstXCam3A *xcam3a, XCamFlickerMode flicker)
 {
     SmartPtr<MainDeviceManager> device_manager = DeviceManagerInstance::device_manager_instance();
-    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_x3a_analyzer ();
+    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_analyzer ();
     return analyzer->set_ae_flicker_mode (flicker);
 }
 XCamFlickerMode gst_xcamsrc_get_exposure_flicker_mode (GstXCam3A *xcam3a)
 {
     SmartPtr<MainDeviceManager> device_manager = DeviceManagerInstance::device_manager_instance();
-    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_x3a_analyzer ();
+    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_analyzer ();
     return analyzer->get_ae_flicker_mode ();
 }
 gint64 gst_xcamsrc_get_current_exposure_time (GstXCam3A *xcam3a)
 {
     SmartPtr<MainDeviceManager> device_manager = DeviceManagerInstance::device_manager_instance();
-    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_x3a_analyzer ();
+    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_analyzer ();
     return analyzer->get_ae_current_exposure_time ();
 }
 double gst_xcamsrc_get_current_analog_gain (GstXCam3A *xcam3a)
 {
     SmartPtr<MainDeviceManager> device_manager = DeviceManagerInstance::device_manager_instance();
-    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_x3a_analyzer ();
+    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_analyzer ();
     return analyzer->get_ae_current_analog_gain ();
 }
 gboolean gst_xcamsrc_set_manual_exposure_time (GstXCam3A *xcam3a, gint64 time_in_us)
 {
     SmartPtr<MainDeviceManager> device_manager = DeviceManagerInstance::device_manager_instance();
-    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_x3a_analyzer ();
+    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_analyzer ();
     return analyzer->set_ae_manual_exposure_time (time_in_us);
 }
 gboolean gst_xcamsrc_set_manual_analog_gain (GstXCam3A *xcam3a, double gain)
 {
     SmartPtr<MainDeviceManager> device_manager = DeviceManagerInstance::device_manager_instance();
-    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_x3a_analyzer ();
+    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_analyzer ();
     return analyzer->set_ae_manual_analog_gain (gain);
 }
 gboolean gst_xcamsrc_set_aperture (GstXCam3A *xcam3a, double fn)
 {
     SmartPtr<MainDeviceManager> device_manager = DeviceManagerInstance::device_manager_instance();
-    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_x3a_analyzer ();
+    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_analyzer ();
     return analyzer->set_ae_aperture (fn);
 }
 gboolean gst_xcamsrc_set_max_analog_gain (GstXCam3A *xcam3a, double max_gain)
 {
     SmartPtr<MainDeviceManager> device_manager = DeviceManagerInstance::device_manager_instance();
-    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_x3a_analyzer ();
+    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_analyzer ();
     return analyzer->set_ae_max_analog_gain (max_gain);
 }
 double gst_xcamsrc_get_max_analog_gain (GstXCam3A *xcam3a)
 {
     SmartPtr<MainDeviceManager> device_manager = DeviceManagerInstance::device_manager_instance();
-    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_x3a_analyzer ();
+    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_analyzer ();
     return analyzer->get_ae_max_analog_gain ();
 }
 gboolean gst_xcamsrc_set_exposure_time_range (GstXCam3A *xcam3a, gint64 min_time_in_us, gint64 max_time_in_us)
 {
     SmartPtr<MainDeviceManager> device_manager = DeviceManagerInstance::device_manager_instance();
-    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_x3a_analyzer ();
+    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_analyzer ();
     return analyzer->set_ae_exposure_time_range (min_time_in_us, max_time_in_us);
 }
 gboolean gst_xcamsrc_get_exposure_time_range (GstXCam3A *xcam3a, gint64 *min_time_in_us, gint64 *max_time_in_us)
 {
     SmartPtr<MainDeviceManager> device_manager = DeviceManagerInstance::device_manager_instance();
-    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_x3a_analyzer ();
+    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_analyzer ();
     return analyzer->get_ae_exposure_time_range (min_time_in_us, max_time_in_us);
 }
 gboolean gst_xcamsrc_set_noise_reduction_level (GstXCam3A *xcam3a, guint8 level)
 {
     SmartPtr<MainDeviceManager> device_manager = DeviceManagerInstance::device_manager_instance();
-    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_x3a_analyzer ();
+    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_analyzer ();
     return analyzer->set_noise_reduction_level (level);
 }
 gboolean gst_xcamsrc_set_temporal_noise_reduction_level (GstXCam3A *xcam3a, guint8 level)
 {
     SmartPtr<MainDeviceManager> device_manager = DeviceManagerInstance::device_manager_instance();
-    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_x3a_analyzer ();
+    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_analyzer ();
     return analyzer->set_temporal_noise_reduction_level (level);
 }
 gboolean gst_xcamsrc_set_gamma_table (GstXCam3A *xcam3a, double *r_table, double *g_table, double *b_table)
 {
     SmartPtr<MainDeviceManager> device_manager = DeviceManagerInstance::device_manager_instance();
-    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_x3a_analyzer ();
+    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_analyzer ();
     return analyzer->set_gamma_table (r_table, g_table, b_table);
 }
 gboolean gst_xcamsrc_set_gbce (GstXCam3A *xcam3a, gboolean enable)
 {
     SmartPtr<MainDeviceManager> device_manager = DeviceManagerInstance::device_manager_instance();
-    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_x3a_analyzer ();
+    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_analyzer ();
     return analyzer->set_gbce (enable);
 }
 gboolean gst_xcamsrc_set_manual_brightness (GstXCam3A *xcam3a, guint8 value)
 {
     SmartPtr<MainDeviceManager> device_manager = DeviceManagerInstance::device_manager_instance();
-    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_x3a_analyzer ();
+    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_analyzer ();
     return analyzer->set_manual_brightness (value);
 }
 gboolean gst_xcamsrc_set_manual_contrast (GstXCam3A *xcam3a, guint8 value)
 {
     SmartPtr<MainDeviceManager> device_manager = DeviceManagerInstance::device_manager_instance();
-    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_x3a_analyzer ();
+    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_analyzer ();
     return analyzer->set_manual_contrast (value);
 }
 gboolean gst_xcamsrc_set_manual_hue (GstXCam3A *xcam3a, guint8 value)
 {
     SmartPtr<MainDeviceManager> device_manager = DeviceManagerInstance::device_manager_instance();
-    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_x3a_analyzer ();
+    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_analyzer ();
     return analyzer->set_manual_hue (value);
 }
 gboolean gst_xcamsrc_set_manual_saturation (GstXCam3A *xcam3a, guint8 value)
 {
     SmartPtr<MainDeviceManager> device_manager = DeviceManagerInstance::device_manager_instance();
-    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_x3a_analyzer ();
+    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_analyzer ();
     return analyzer->set_manual_saturation (value);
 }
 gboolean gst_xcamsrc_set_manual_sharpness (GstXCam3A *xcam3a, guint8 value)
 {
     SmartPtr<MainDeviceManager> device_manager = DeviceManagerInstance::device_manager_instance();
-    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_x3a_analyzer ();
+    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_analyzer ();
     return analyzer->set_manual_sharpness (value);
 }
 gboolean gst_xcamsrc_set_dvs (GstXCam3A *xcam3a, gboolean enable)
 {
     SmartPtr<MainDeviceManager> device_manager = DeviceManagerInstance::device_manager_instance();
-    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_x3a_analyzer ();
+    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_analyzer ();
     return analyzer->set_dvs (enable);
 }
 gboolean gst_xcamsrc_set_night_mode (GstXCam3A *xcam3a, gboolean enable)
 {
     SmartPtr<MainDeviceManager> device_manager = DeviceManagerInstance::device_manager_instance();
-    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_x3a_analyzer ();
+    SmartPtr<X3aAnalyzer> analyzer = device_manager->get_analyzer ();
     return analyzer->set_night_mode (enable);
 }
 
diff --git a/wrapper/gstreamer/stub.h b/wrapper/gstreamer/stub.h
index 2112815..a3165ed 100644
--- a/wrapper/gstreamer/stub.h
+++ b/wrapper/gstreamer/stub.h
@@ -29,6 +29,11 @@
 #include <gst/video/gstvideopool.h>
 #include "gstxcaminterface.h"
 #include "gstxcambufferpool.h"
+extern "C" {
+#include <drm.h>
+#include <drm_mode.h>
+#include <intel_bufmgr.h>
+}
 
 XCAM_BEGIN_DECLARE
 
diff --git a/wrapper/gstreamer/v4l2dev.cpp b/wrapper/gstreamer/v4l2dev.cpp
index d259242..4e5b465 100644
--- a/wrapper/gstreamer/v4l2dev.cpp
+++ b/wrapper/gstreamer/v4l2dev.cpp
@@ -35,51 +35,12 @@
     return _device_manager;
 }
 
-
-const char*         MainDeviceManager::_capture_device_name (NULL);
-const char*         MainDeviceManager::_event_device_name (NULL);
-const char*         MainDeviceManager::_cpf_file_name (NULL);
-
 MainDeviceManager::MainDeviceManager()
 {
-    _device = new AtomispDevice (_capture_device_name);
-    _sub_device = new V4l2SubDevice (_event_device_name);
-    _isp_controller = new IspController (_device);
-
-#if HAVE_IA_AIQ
-    _x3a_analyzer = new X3aAnalyzerAiq (_isp_controller, _cpf_file_name);
-#else
-    _x3a_analyzer = new X3aAnalyzerSimple ();
-#endif
-
-    _image_processor = new IspImageProcessor (_isp_controller);
-
-    this->set_capture_device (_device);
-    this->set_event_device (_sub_device);
-    this->set_isp_controller (_isp_controller);
-    this->set_analyzer (_x3a_analyzer);
-    this->add_image_processor (_image_processor);
 }
 
 MainDeviceManager::~MainDeviceManager()
-{}
-
-void
-MainDeviceManager::set_capture_device_name (const char* name)
 {
-    _capture_device_name = name;
-}
-
-void
-MainDeviceManager::set_event_device_name (const char* name)
-{
-    _event_device_name = name;
-}
-
-void
-MainDeviceManager::set_cpf_file_name (const char* name)
-{
-    _cpf_file_name = name;
 }
 
 void
@@ -98,9 +59,4 @@
     pthread_mutex_unlock (&bufs_mutex);
 }
 
-SmartPtr<X3aAnalyzer> &
-MainDeviceManager::get_x3a_analyzer () {
-    return _x3a_analyzer;
-}
-
 };
diff --git a/wrapper/gstreamer/v4l2dev.h b/wrapper/gstreamer/v4l2dev.h
index 2d3411b..9fab928 100644
--- a/wrapper/gstreamer/v4l2dev.h
+++ b/wrapper/gstreamer/v4l2dev.h
@@ -32,6 +32,9 @@
 #include "device_manager.h"
 #include "isp_controller.h"
 #include "isp_image_processor.h"
+#if HAVE_LIBCL
+#include "cl_3a_image_processor.h"
+#endif
 #if HAVE_IA_AIQ
 #include "x3a_analyzer_aiq.h"
 #endif
@@ -64,18 +67,21 @@
     MainDeviceManager ();
     ~MainDeviceManager ();
 
-    SmartPtr<V4l2Device> get_device() {
+    SmartPtr<V4l2Device>& get_capture_device () {
         return _device;
     }
-    SmartPtr<V4l2SubDevice> get_sub_device() {
-        return _sub_device;
+
+    SmartPtr<V4l2SubDevice>& get_event_device () {
+        return _subdevice;
     }
 
-    static void set_capture_device_name (const char*);
-    static void set_event_device_name (const char*);
-    static void set_cpf_file_name (const char*);
+    SmartPtr<IspController>& get_isp_controller () {
+        return _isp_controller;
+    }
 
-    SmartPtr<X3aAnalyzer>& get_x3a_analyzer ();
+    SmartPtr<X3aAnalyzer>& get_analyzer () {
+        return _3a_analyzer;
+    }
 
 protected:
     virtual void handle_message (SmartPtr<XCamMessage> &msg);
@@ -87,17 +93,6 @@
     pthread_cond_t          bufs_cond;
     std::queue< SmartPtr<VideoBuffer> > release_bufs;
     pthread_mutex_t         release_mutex;
-
-private:
-    SmartPtr<V4l2Device>        _device;
-    SmartPtr<V4l2SubDevice>     _sub_device;
-    SmartPtr<IspController>     _isp_controller;
-    SmartPtr<X3aAnalyzer>       _x3a_analyzer;
-    SmartPtr<ImageProcessor>        _image_processor;
-
-    static const char*          _capture_device_name;
-    static const char*          _event_device_name;
-    static const char*          _cpf_file_name;
 };
 
 };
diff --git a/xcore/buffer_pool.cpp b/xcore/buffer_pool.cpp
index 1e36c6d..a761af4 100644
--- a/xcore/buffer_pool.cpp
+++ b/xcore/buffer_pool.cpp
@@ -59,6 +59,13 @@
     return _data->unmap ();
 }
 
+int
+BufferProxy::get_fd ()
+{
+    XCAM_ASSERT (_data.ptr ());
+    return _data->get_fd ();
+}
+
 BufferPool::BufferPool ()
     : _allocated_num (0)
     , _max_count (0)
diff --git a/xcore/buffer_pool.h b/xcore/buffer_pool.h
index c96b6d1..6167f8f 100644
--- a/xcore/buffer_pool.h
+++ b/xcore/buffer_pool.h
@@ -37,6 +37,9 @@
 
     virtual uint8_t *map () = 0;
     virtual bool unmap () = 0;
+    virtual int get_fd () {
+        return -1;
+    }
 
 private:
     XCAM_DEAD_COPY (BufferData);
@@ -60,6 +63,7 @@
     // derived from VideoBuffer
     virtual uint8_t *map ();
     virtual bool unmap ();
+    virtual int get_fd();
 
 protected:
     SmartPtr<BufferData> &get_buffer_data () {
diff --git a/xcore/drm_bo_buffer.cpp b/xcore/drm_bo_buffer.cpp
index 1dd1c2d..4d2dac2 100644
--- a/xcore/drm_bo_buffer.cpp
+++ b/xcore/drm_bo_buffer.cpp
@@ -26,6 +26,7 @@
     : _display (display)
     , _bo (bo)
     , _buf (NULL)
+    , _prime_fd (-1)
 {
     XCAM_ASSERT (display.ptr ());
     XCAM_ASSERT (bo);
@@ -60,6 +61,19 @@
     return true;
 }
 
+int
+DrmBoData::get_fd ()
+{
+    if (_prime_fd == -1) {
+        if (drm_intel_bo_gem_export_to_prime (_bo, &_prime_fd) < 0) {
+            _prime_fd = -1;
+            XCAM_LOG_ERROR ("DrmBoData: failed to obtain prime fd");
+        }
+    }
+
+    return _prime_fd;
+}
+
 DrmBoBuffer::DrmBoBuffer (const VideoBufferInfo &info, const SmartPtr<DrmBoData> &data)
     : BufferProxy (info, data)
 {
diff --git a/xcore/drm_bo_buffer.h b/xcore/drm_bo_buffer.h
index 54a8bbc..53e62fa 100644
--- a/xcore/drm_bo_buffer.h
+++ b/xcore/drm_bo_buffer.h
@@ -45,6 +45,7 @@
     //derived from BufferData
     virtual uint8_t *map ();
     virtual bool unmap ();
+    virtual int get_fd ();
 
 protected:
     explicit DrmBoData (SmartPtr<DrmDisplay> &display, drm_intel_bo *bo);
@@ -55,6 +56,7 @@
     SmartPtr<DrmDisplay>       _display;
     drm_intel_bo              *_bo;
     uint8_t                   *_buf;
+    int                       _prime_fd;
 };
 
 class DrmBoBuffer
diff --git a/xcore/v4l2_buffer_proxy.cpp b/xcore/v4l2_buffer_proxy.cpp
index d006ab1..d33fa5c 100644
--- a/xcore/v4l2_buffer_proxy.cpp
+++ b/xcore/v4l2_buffer_proxy.cpp
@@ -46,6 +46,12 @@
     return true;
 }
 
+int
+V4l2Buffer::get_fd ()
+{
+    return _buf.m.fd;
+}
+
 V4l2BufferProxy::V4l2BufferProxy (SmartPtr<V4l2Buffer> &buf, SmartPtr<V4l2Device> &device)
     : BufferProxy (buf)
     , _device (device)
diff --git a/xcore/v4l2_buffer_proxy.h b/xcore/v4l2_buffer_proxy.h
index 67a9a4e..61a7cfa 100644
--- a/xcore/v4l2_buffer_proxy.h
+++ b/xcore/v4l2_buffer_proxy.h
@@ -71,6 +71,7 @@
     // derived from BufferData
     virtual uint8_t *map ();
     virtual bool unmap ();
+    virtual int get_fd ();
 
 private:
     XCAM_DEAD_COPY (V4l2Buffer);
diff --git a/xcore/v4l2_device.cpp b/xcore/v4l2_device.cpp
index eaee632..2e99357 100644
--- a/xcore/v4l2_device.cpp
+++ b/xcore/v4l2_device.cpp
@@ -238,7 +238,7 @@
             XCAM_LOG_ERROR("Video device is busy, fail to set format.");
         } else {
             // TODO log format details and errno
-            XCAM_LOG_ERROR("Fail to set format.");
+            XCAM_LOG_ERROR("Fail to set format: %s", strerror(errno));
         }
 
         return XCAM_RETURN_ERROR_IOCTL;
@@ -310,7 +310,6 @@
 
     if (bytes_perline != 0)
         format.fmt.pix.bytesperline = bytes_perline;
-
     return set_format (format);
 }
 
diff --git a/xcore/video_buffer.h b/xcore/video_buffer.h
index 629bc3c..f35c973 100644
--- a/xcore/video_buffer.h
+++ b/xcore/video_buffer.h
@@ -92,6 +92,7 @@
 
     virtual uint8_t *map () = 0;
     virtual bool unmap () = 0;
+    virtual int get_fd () = 0;
 
     const VideoBufferInfo & get_video_info () const {
         return _videoinfo;
@@ -108,6 +109,9 @@
         _timestamp = timestamp;
     }
 
+    uint32_t get_size () const {
+        return _videoinfo.size;
+    }
 private:
     VideoBufferInfo _videoinfo;
     int64_t         _timestamp; // in microseconds