init libxcam source code
diff --git a/xcore/Makefile.am b/xcore/Makefile.am
new file mode 100644
index 0000000..a3d5ba6
--- /dev/null
+++ b/xcore/Makefile.am
@@ -0,0 +1,131 @@
+lib_LTLIBRARIES = libxcam_core.la
+
+PTHREAD_LDFLAGS = -pthread
+
+XCAM_CORE_CXXFLAGS = $(XCAM_CXXFLAGS)
+XCAM_CORE_LIBS =    \
+	$(NULL)
+
+if DEBUG
+endif
+
+if HAVE_IA_AIQ
+if USE_LOCAL_AIQ
+IA_IMAGING_CFLAGS =  \
+	-I$(top_srcdir)/ext/ia_imaging/include \
+	$(NULL)
+
+IA_IMAGING_LIBS =            \
+	-L$(top_srcdir)/ext/ia_imaging/lib \
+	-lia_aiq                 \
+	-lia_isp_2_2             \
+	-lia_cmc_parser          \
+	-lia_mkn                 \
+	-lia_nvm                 \
+	-lia_tools               \
+	-lia_log                 \
+	$(NULL)
+
+else
+IA_IMAGING_CFLAGS =  $(IA_AIQ_CFLAGS)
+IA_IMAGING_LIBS =  $(IA_AIQ_LIBS)
+endif
+
+XCAM_CORE_CXXFLAGS +=             \
+	$(IA_IMAGING_CFLAGS)     \
+	$(NULL)
+
+XCAM_CORE_LIBS +=                 \
+	$(IA_IMAGING_LIBS)       \
+	$(NULL)
+
+endif
+
+
+if HAVE_LIBDRM
+XCAM_CORE_CXXFLAGS += $(LIBDRM_CFLAGS)
+XCAM_CORE_LIBS += $(LIBDRM_LIBS)
+endif
+
+if USE_LOCAL_ATOMISP
+XCAM_CORE_CXXFLAGS +=        \
+	-I$(top_srcdir)/ext/atomisp \
+	$(NULL)
+endif
+
+xcam_sources =               \
+	atomisp_device.cpp       \
+	device_manager.cpp       \
+	handler_interface.cpp    \
+	image_processor.cpp      \
+	isp_controller.cpp       \
+	isp_image_processor.cpp  \
+	isp_config_translator.cpp \
+	poll_thread.cpp          \
+	sensor_descriptor.cpp    \
+	v4l2_buffer_proxy.cpp    \
+	v4l2_device.cpp          \
+	x3a_analyzer.cpp         \
+	x3a_analyzer_manager.cpp \
+	x3a_analyzer_simple.cpp  \
+	x3a_image_process_center.cpp  \
+	x3a_isp_config.cpp       \
+	x3a_result.cpp           \
+	x3a_statistics_queue.cpp \
+	xcam_common.cpp          \
+	xcam_thread.cpp          \
+	$(NULL)
+
+if HAVE_IA_AIQ
+xcam_sources +=              \
+	libtbd.c                 \
+	xcam_cpf_reader.c        \
+	aiq_handler.cpp          \
+	x3a_analyzer_aiq.cpp     \
+	$(NULL)
+endif
+
+libxcam_core_la_CXXFLAGS  =  \
+	$(XCAM_CORE_CXXFLAGS)         \
+	$(NULL)
+
+libxcam_core_la_SOURCES =    \
+	$(xcam_sources)          \
+	$(NULL)
+
+libxcam_core_la_LDFLAGS =    \
+	-no-undefined            \
+	$(PTHREAD_LDFLAGS)       \
+	$(NULL)
+
+libxcam_core_la_LIBADD =     \
+	$(XCAM_CORE_LIBS)             \
+	$(NULL)
+
+
+libxcam_coreincludedir =  $(includedir)/xcam
+
+libxcam_coreinclude_HEADERS =  \
+	device_manager.h           \
+	handler_interface.h        \
+	image_processor.h          \
+	safe_list.h                \
+	smartptr.h                 \
+	v4l2_buffer_proxy.h        \
+	v4l2_device.h              \
+	video_buffer.h             \
+	x3a_analyzer.h             \
+	x3a_analyzer_manager.h     \
+	x3a_event.h                \
+	x3a_image_process_center.h \
+	x3a_isp_config.h           \
+	x3a_result.h               \
+	xcam_3a_result.h           \
+	xcam_3a_types.h            \
+	xcam_common.h              \
+	xcam_defs.h                \
+	xcam_mutex.h               \
+	xcam_thread.h              \
+	xcam_utils.h               \
+	$(NULL)
+
diff --git a/xcore/aiq_handler.cpp b/xcore/aiq_handler.cpp
new file mode 100644
index 0000000..dc3ec7a
--- /dev/null
+++ b/xcore/aiq_handler.cpp
@@ -0,0 +1,1103 @@
+/*
+ * aiq_handler.cpp - AIQ handler
+ *
+ *  Copyright (c) 2012-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: Wind Yuan <feng.yuan@intel.com>
+ * Author: Yan Zhang <yan.y.zhang@intel.com>
+ */
+
+#include "aiq_handler.h"
+#include "x3a_isp_config.h"
+
+#include <string.h>
+#include <math.h>
+
+#include "ia_isp_2_2.h"
+
+#define MAX_STATISTICS_WIDTH 150
+#define MAX_STATISTICS_HEIGHT 150
+
+namespace XCam {
+
+struct IspInputParameters {
+    ia_aiq_frame_use            frame_use;
+    ia_aiq_frame_params        *sensor_frame_params;
+    ia_aiq_exposure_parameters *exposure_results;
+    ia_aiq_awb_results         *awb_results;
+    ia_aiq_gbce_results        *gbce_results;
+    ia_aiq_pa_results          *pa_results;
+    int8_t                      manual_brightness;
+    int8_t                      manual_contrast;
+    int8_t                      manual_hue;
+    int8_t                      manual_saturation;
+    int8_t                      manual_sharpness;
+    int8_t                      manual_nr_level;
+    ia_isp_effect               effects;
+
+    IspInputParameters ()
+        : frame_use (ia_aiq_frame_use_preview)
+        , sensor_frame_params (NULL)
+        , exposure_results (NULL)
+        , awb_results (NULL)
+        , gbce_results (NULL)
+        , pa_results (NULL)
+        , manual_brightness (0)
+        , manual_contrast (0)
+        , manual_hue (0)
+        , manual_saturation (0)
+        , manual_sharpness (0)
+        , manual_nr_level (0)
+        , effects (ia_isp_effect_none)
+    {}
+};
+
+class IaIspAdaptor22
+    : public IaIspAdaptor
+{
+public:
+    IaIspAdaptor22 () {
+        xcam_mem_clear (&_input_params);
+    }
+    ~IaIspAdaptor22 () {
+        if (_handle)
+            ia_isp_2_2_deinit (_handle);
+    }
+
+    virtual bool init (
+        const ia_binary_data *cpf,
+        unsigned int max_width,
+        unsigned int max_height,
+        ia_cmc_t *cmc,
+        ia_mkn *mkn);
+
+    virtual bool convert_statistics (
+        void *statistics,
+        ia_aiq_rgbs_grid **out_rgbs_grid,
+        ia_aiq_af_grid **out_af_grid);
+
+    virtual bool run (
+        const IspInputParameters *isp_input_params,
+        ia_binary_data *output_data);
+
+private:
+    ia_isp_2_2_input_params  _input_params;
+
+};
+
+bool
+IaIspAdaptor22::init (
+    const ia_binary_data *cpf,
+    unsigned int max_width,
+    unsigned int max_height,
+    ia_cmc_t *cmc,
+    ia_mkn *mkn)
+{
+    xcam_mem_clear (&_input_params);
+    _input_params.isp_vamem_type = 1;
+    _handle = ia_isp_2_2_init (cpf, max_width, max_height, cmc, mkn);
+    XCAM_FAIL_RETURN (ERROR, _handle, false, "ia_isp 2.2 init failed");
+    return true;
+}
+
+bool
+IaIspAdaptor22::convert_statistics (
+    void *statistics,
+    ia_aiq_rgbs_grid **out_rgbs_grid,
+    ia_aiq_af_grid **out_af_grid)
+{
+    ia_err err;
+    err = ia_isp_2_2_statistics_convert (_handle, statistics, out_rgbs_grid, out_af_grid);
+    XCAM_FAIL_RETURN (ERROR, err == ia_err_none, false, "ia_isp 2.2 convert stats failed");
+    return true;
+}
+
+bool
+IaIspAdaptor22::run (
+    const IspInputParameters *isp_input_params,
+    ia_binary_data *output_data)
+{
+    ia_err err;
+
+    _input_params.frame_use = isp_input_params->frame_use;
+    _input_params.sensor_frame_params = isp_input_params->sensor_frame_params;
+    _input_params.exposure_results = isp_input_params->exposure_results;
+    _input_params.awb_results = isp_input_params->awb_results;
+    _input_params.gbce_results = isp_input_params->gbce_results;
+    _input_params.pa_results = isp_input_params->pa_results;
+    _input_params.manual_brightness = isp_input_params->manual_brightness;
+    _input_params.manual_contrast = isp_input_params->manual_contrast;
+    _input_params.manual_hue = isp_input_params->manual_hue;
+    _input_params.manual_saturation = isp_input_params->manual_saturation;
+    _input_params.nr_setting.feature_level = ia_isp_feature_level_high;
+    _input_params.nr_setting.strength = isp_input_params->manual_nr_level;
+    _input_params.ee_setting.feature_level = ia_isp_feature_level_high;
+    _input_params.ee_setting.strength = isp_input_params->manual_sharpness;
+    _input_params.effects = isp_input_params->effects;
+
+    err = ia_isp_2_2_run (_handle, &_input_params, output_data);
+    XCAM_FAIL_RETURN (ERROR, err == ia_err_none, false, "ia_isp 2.2 run failed");
+    return true;
+}
+
+#if 0
+
+class IaIspAdaptor15
+    : public IaIspAdaptor
+{
+public:
+    IaIspAdaptor15 () {
+        xcam_mem_clear (&_input_params);
+    }
+    ~IaIspAdaptor15 () {
+        if (_handle)
+            ia_isp_1_5_deinit (_handle);
+    }
+    virtual bool init (
+        const ia_binary_data *cpf,
+        unsigned int max_width,
+        unsigned int max_height,
+        ia_cmc_t *cmc,
+        ia_mkn *mkn);
+    virtual bool convert_statistics (
+        void *statistics,
+        ia_aiq_rgbs_grid **out_rgbs_grid,
+        ia_aiq_af_grid **out_af_grid);
+    virtual bool run (
+        const IspInputParameters *isp_input_params,
+        ia_binary_data *output_data);
+
+private:
+    ia_isp_1_5_input_params  _input_params;
+
+};
+
+bool
+IaIspAdaptor15::init (
+    const ia_binary_data *cpf,
+    unsigned int max_width,
+    unsigned int max_height,
+    ia_cmc_t *cmc,
+    ia_mkn *mkn)
+{
+    xcam_mem_clear (&_input_params);
+    _input_params.isp_vamem_type = 1;
+    _handle = ia_isp_1_5_init (cpf, max_width, max_height, cmc, mkn);
+    XCAM_FAIL_RETURN (ERROR, _handle, false, "ia_isp 1.5 init failed");
+    return true;
+}
+
+bool
+IaIspAdaptor15::convert_statistics (
+    void *statistics,
+    ia_aiq_rgbs_grid **out_rgbs_grid,
+    ia_aiq_af_grid **out_af_grid)
+{
+    ia_err err;
+    err = ia_isp_1_5_statistics_convert (_handle, statistics, out_rgbs_grid, out_af_grid);
+    XCAM_FAIL_RETURN (ERROR, err == ia_err_none, false, "ia_isp 1.5 convert stats failed");
+    return true;
+}
+
+bool
+IaIspAdaptor15::run (
+    const IspInputParameters *isp_input_params,
+    ia_binary_data *output_data)
+{
+    ia_err err;
+
+    _input_params.frame_use = isp_input_params->frame_use;
+    _input_params.sensor_frame_params = isp_input_params->sensor_frame_params;
+    _input_params.exposure_results = isp_input_params->exposure_results;
+    _input_params.awb_results = isp_input_params->awb_results;
+    _input_params.gbce_results = isp_input_params->gbce_results;
+    _input_params.pa_results = isp_input_params->pa_results;
+    _input_params.manual_brightness = isp_input_params->manual_brightness;
+    _input_params.manual_contrast = isp_input_params->manual_contrast;
+    _input_params.manual_hue = isp_input_params->manual_hue;
+    _input_params.manual_saturation = isp_input_params->manual_saturation;
+    _input_params.nr_setting.feature_level = ia_isp_feature_level_high;
+    _input_params.nr_setting.strength = isp_input_params->manual_nr_level;
+    _input_params.ee_setting.feature_level = ia_isp_feature_level_high;
+    _input_params.ee_setting.strength = isp_input_params->manual_sharpness;
+    _input_params.effects = isp_input_params->effects;
+
+    err = ia_isp_1_5_run (_handle, &_input_params, output_data);
+    XCAM_FAIL_RETURN (ERROR, err == ia_err_none, false, "ia_isp 1.5 run failed");
+    return true;
+}
+
+#endif
+
+static double
+_calculate_new_value_by_speed (double start, double end, double speed)
+{
+    XCAM_ASSERT (speed >= 0.0 && speed <= 1.0);
+    static const double value_equal_range = 0.000001;
+
+    if (fabs (end - start) <= value_equal_range)
+        return end;
+    return (start * (1.0 - speed) + end * speed);
+}
+
+static double
+_imx185_sensor_gain_code_to_mutiplier (uint32_t code)
+{
+    /* 185 sensor code : DB = 160 : 48 */
+    double db;
+    db = code * 48.0 / 160.0;
+    return pow (10.0, db / 20.0);
+}
+
+static uint32_t
+_mutiplier_to_imx185_sensor_gain_code (double mutiplier)
+{
+    double db = log10 (mutiplier) * 20;
+    if (db > 48)
+        db = 48;
+    return (uint32_t) (db * 160 / 48);
+}
+
+static uint32_t
+_time_to_coarse_line (ia_aiq_exposure_sensor_descriptor *desc, uint32_t time_us)
+{
+    float value =  time_us * desc->pixel_clock_freq_mhz;
+
+    value = (value + desc->pixel_periods_per_line / 2) / desc->pixel_periods_per_line;
+    return (uint32_t)(value);
+}
+
+AiqAeHandler::AiqAeResult::AiqAeResult()
+{
+    xcam_mem_clear (&ae_result);
+    xcam_mem_clear (&ae_exp_ret);
+    xcam_mem_clear (&aiq_exp_param);
+    xcam_mem_clear (&sensor_exp_param);
+    xcam_mem_clear (&weight_grid);
+    xcam_mem_clear (&flash_param);
+}
+
+void
+AiqAeHandler::AiqAeResult::copy (ia_aiq_ae_results *result)
+{
+    XCAM_ASSERT (result);
+
+    this->ae_result = *result;
+    this->aiq_exp_param = *result->exposures[0].exposure;
+    this->sensor_exp_param = *result->exposures[0].sensor_exposure;
+    this->weight_grid = *result->weight_grid;
+    this->flash_param = *result->flash;
+
+    this->ae_exp_ret.exposure = &this->aiq_exp_param;
+    this->ae_exp_ret.sensor_exposure = &this->sensor_exp_param;
+    this->ae_result.exposures = &this->ae_exp_ret;
+    this->ae_result.weight_grid = &this->weight_grid;
+    this->ae_result.flash = &this->flash_param;
+    this->ae_result.num_exposures = 1;
+}
+
+AiqAeHandler::AiqAeHandler (SmartPtr<AiqCompositor> &aiq_compositor)
+    : _aiq_compositor (aiq_compositor)
+    , _started (false)
+{
+    xcam_mem_clear (&_ia_ae_window);
+    xcam_mem_clear (&_sensor_descriptor);
+    xcam_mem_clear (&_manual_limits);
+    xcam_mem_clear (&_input);
+    _input.num_exposures = 1;
+    _input.frame_use = _aiq_compositor->get_frame_use();
+    _input.flash_mode = ia_aiq_flash_mode_off;
+    _input.operation_mode = ia_aiq_ae_operation_mode_automatic;
+    _input.metering_mode = ia_aiq_ae_metering_mode_evaluative;
+    _input.priority_mode = ia_aiq_ae_priority_mode_normal;
+    _input.flicker_reduction_mode = ia_aiq_ae_flicker_reduction_auto;
+    _input.sensor_descriptor = NULL;
+    _input.exposure_window = NULL;
+    _input.exposure_coordinate = NULL;
+    _input.ev_shift = 0.0;
+    _input.manual_exposure_time_us = -1;
+    _input.manual_analog_gain = -1.0;
+    _input.manual_iso = -1.0;
+    _input.aec_features = NULL;
+    _input.manual_limits = NULL;
+}
+
+bool
+AiqAeHandler::set_description (struct atomisp_sensor_mode_data *sensor_data)
+{
+    XCAM_ASSERT (sensor_data);
+
+    _sensor_descriptor.pixel_clock_freq_mhz = sensor_data->vt_pix_clk_freq_mhz / 1000000.0f;
+    _sensor_descriptor.pixel_periods_per_line = sensor_data->line_length_pck;
+    _sensor_descriptor.line_periods_per_field = sensor_data->frame_length_lines;
+    _sensor_descriptor.line_periods_vertical_blanking = sensor_data->frame_length_lines
+            - (sensor_data->crop_vertical_end - sensor_data->crop_vertical_start + 1)
+            / sensor_data->binning_factor_y;
+    _sensor_descriptor.fine_integration_time_min = sensor_data->fine_integration_time_def;
+    _sensor_descriptor.fine_integration_time_max_margin = sensor_data->line_length_pck - sensor_data->fine_integration_time_def;
+    _sensor_descriptor.coarse_integration_time_min = sensor_data->coarse_integration_time_min;
+    _sensor_descriptor.coarse_integration_time_max_margin = sensor_data->coarse_integration_time_max_margin;
+
+    return true;
+}
+
+bool
+AiqAeHandler::ensure_ia_parameters ()
+{
+    bool ret = true;
+    ret = ret && ensure_ae_mode ();
+    ret = ret && ensure_ae_metering_mode ();
+    ret = ret && ensure_ae_priority_mode ();
+    ret = ret && ensure_ae_flicker_mode ();
+    ret = ret && ensure_ae_manual ();
+    ret = ret && ensure_ae_ev_shift ();
+    _input.sensor_descriptor = &_sensor_descriptor;
+    return ret;
+}
+
+bool AiqAeHandler::ensure_ae_mode ()
+{
+    XCamAeMode mode = this->get_mode_unlock();
+    switch (mode) {
+    case XCAM_AE_MODE_AUTO:
+    case XCAM_AE_MODE_MANUAL:
+        _input.operation_mode = ia_aiq_ae_operation_mode_automatic;
+        break;
+
+    case XCAM_AE_MODE_NOT_SET:
+    default:
+        XCAM_LOG_ERROR("unsupported ae mode:%d", mode);
+        return false;
+    }
+    return true;
+}
+bool AiqAeHandler::ensure_ae_metering_mode ()
+{
+    XCamAeMeteringMode mode = this->get_metering_mode_unlock();
+
+    _input.exposure_window = NULL;
+
+    switch (mode) {
+    case XCAM_AE_METERING_MODE_AUTO:
+        _input.metering_mode = ia_aiq_ae_metering_mode_evaluative;
+        break;
+    case XCAM_AE_METERING_MODE_SPOT:
+    {
+        _input.metering_mode = ia_aiq_ae_metering_mode_evaluative;
+        const XCam3AWindow & window = this->get_window_unlock();
+        if (window.x_end > window.x_start &&
+                window.y_end > window.y_start) {
+            _aiq_compositor->convert_window_to_ia(window, _ia_ae_window);
+            _input.exposure_window = &_ia_ae_window;
+        }
+    }
+    break;
+    case XCAM_AE_METERING_MODE_CENTER:
+        _input.metering_mode = ia_aiq_ae_metering_mode_center;
+        break;
+    default:
+        XCAM_LOG_ERROR("unsupported ae mode:%d", mode);
+        return false;
+    }
+    return true;
+}
+
+bool AiqAeHandler::ensure_ae_priority_mode ()
+{
+    _input.priority_mode = ia_aiq_ae_priority_mode_normal;
+    return true;
+}
+
+bool AiqAeHandler::ensure_ae_flicker_mode ()
+{
+    XCamFlickerMode mode = this->get_flicker_mode_unlock ();
+    switch (mode) {
+    case XCAM_AE_FLICKER_MODE_AUTO:
+        _input.flicker_reduction_mode = ia_aiq_ae_flicker_reduction_auto;
+        break;
+    case XCAM_AE_FLICKER_MODE_50HZ:
+        _input.flicker_reduction_mode = ia_aiq_ae_flicker_reduction_50hz;
+        break;
+    case XCAM_AE_FLICKER_MODE_60HZ:
+        _input.flicker_reduction_mode = ia_aiq_ae_flicker_reduction_60hz;
+        break;
+    case XCAM_AE_FLICKER_MODE_OFF:
+        _input.flicker_reduction_mode = ia_aiq_ae_flicker_reduction_off;
+        break;
+    default:
+        XCAM_LOG_ERROR ("flicker mode(%d) unknown", mode);
+        return false;
+    }
+    return true;
+}
+
+bool AiqAeHandler::ensure_ae_manual ()
+{
+    _input.manual_exposure_time_us = this->_manual_exposure_time;
+    _input.manual_analog_gain = this->_manual_analog_gain;
+    return true;
+}
+
+bool AiqAeHandler::ensure_ae_ev_shift ()
+{
+    _input.ev_shift = this->get_ev_shift_unlock();
+    return true;
+}
+
+SmartPtr<X3aResult>
+AiqAeHandler::pop_result ()
+{
+    //AnalyzerHandler::HanlderLock lock(this);
+
+    X3aIspExposureResult *result = new X3aIspExposureResult(XCAM_IMAGE_PROCESS_ONCE);
+    struct atomisp_exposure sensor;
+    XCam3aResultExposure exposure;
+
+    xcam_mem_clear (&sensor);
+    sensor.integration_time[0] = _result.sensor_exp_param.coarse_integration_time;
+    sensor.integration_time[1] = _result.sensor_exp_param.fine_integration_time;
+    sensor.gain[0] = _result.sensor_exp_param.analog_gain_code_global;
+    sensor.gain[1] = _result.sensor_exp_param.digital_gain_global;
+    result->set_isp_config (sensor);
+
+    xcam_mem_clear (&exposure);
+    exposure.exposure_time = _result.aiq_exp_param.exposure_time_us;
+    exposure.analog_gain = _result.aiq_exp_param.analog_gain;
+    exposure.digital_gain = _result.aiq_exp_param.digital_gain;
+    exposure.aperture = _result.aiq_exp_param.aperture_fn;
+    result->set_standard_result (exposure);
+
+    return result;
+}
+
+XCamReturn
+AiqAeHandler::analyze (X3aResultList &output)
+{
+    ia_aiq  *ia_handle = NULL;
+    ia_aiq_ae_results *ae_result = NULL;
+    ia_aiq_exposure_sensor_parameters *cur_sensor_result = NULL;
+    ia_err ia_error = ia_err_none;
+    bool need_apply = false;
+    SmartPtr<X3aResult> result;
+
+    AnalyzerHandler::HanlderLock lock(this);
+
+    if (!ensure_ia_parameters ()) {
+        XCAM_LOG_ERROR ("AIQ AE ensure ia parameters failed");
+        return XCAM_RETURN_ERROR_PARAM;
+    }
+
+    ia_handle = _aiq_compositor->get_handle ();
+    XCAM_ASSERT (ia_handle);
+    ia_error = ia_aiq_ae_run (ia_handle, &_input, &ae_result);
+    XCAM_FAIL_RETURN (ERROR, ia_error == ia_err_none, XCAM_RETURN_ERROR_AIQ, "AIQ run AE failed");
+
+    cur_sensor_result = ae_result->exposures[0].sensor_exposure;
+
+    if (!_started) {
+        _result.copy (ae_result);
+        _started = true;
+        need_apply = true;
+    } else {
+        //TODO
+        ia_aiq_exposure_sensor_parameters *last_sensor_res = &_result.sensor_exp_param;
+        if (last_sensor_res->coarse_integration_time !=  cur_sensor_result->coarse_integration_time ||
+                last_sensor_res->fine_integration_time !=  cur_sensor_result->fine_integration_time ||
+                last_sensor_res->analog_gain_code_global !=  cur_sensor_result->analog_gain_code_global ||
+                last_sensor_res->digital_gain_global !=  cur_sensor_result->digital_gain_global) {
+            ia_aiq_exposure_sensor_parameters cur_cp_res = *cur_sensor_result;
+            if (!manual_control_result (cur_cp_res, *last_sensor_res)) {
+                XCAM_LOG_WARNING ("manual control AE result failed");
+            }
+            _result.copy (ae_result);
+            _result.sensor_exp_param = cur_cp_res;
+            need_apply = true;
+        }
+    }
+
+    if (need_apply) {
+        result = pop_result ();
+        if (result.ptr())
+            output.push_back (result);
+    }
+
+    return XCAM_RETURN_NO_ERROR;
+}
+
+bool
+AiqAeHandler::manual_control_result (
+    ia_aiq_exposure_sensor_parameters &cur_res,
+    const ia_aiq_exposure_sensor_parameters &last_res)
+{
+    adjust_ae_speed (cur_res, last_res, this->get_speed_unlock());
+    adjust_ae_limitation (cur_res);
+
+    return true;
+}
+
+void
+AiqAeHandler::adjust_ae_speed (
+    ia_aiq_exposure_sensor_parameters &cur_res,
+    const ia_aiq_exposure_sensor_parameters &last_res,
+    double ae_speed)
+{
+    double last_gain, input_gain, ret_gain;
+    ia_aiq_exposure_sensor_parameters tmp_res;
+
+    if (XCAM_DOUBLE_EQUAL_AROUND(ae_speed, 1.0 ))
+        return;
+    xcam_mem_clear (&tmp_res);
+    tmp_res.coarse_integration_time = _calculate_new_value_by_speed (
+                                          last_res.coarse_integration_time,
+                                          cur_res.coarse_integration_time,
+                                          ae_speed);
+
+    last_gain = _imx185_sensor_gain_code_to_mutiplier (last_res.analog_gain_code_global);
+    input_gain = _imx185_sensor_gain_code_to_mutiplier (cur_res.analog_gain_code_global);
+    ret_gain = _calculate_new_value_by_speed (last_gain, input_gain, ae_speed);
+
+    tmp_res.analog_gain_code_global = _mutiplier_to_imx185_sensor_gain_code (ret_gain);
+
+    XCAM_LOG_DEBUG ("AE speed: from (shutter:%d, gain:%d[%.03f]) to (shutter:%d, gain:%d[%.03f])",
+                    cur_res.coarse_integration_time, cur_res.analog_gain_code_global, input_gain,
+                    tmp_res.coarse_integration_time, tmp_res.analog_gain_code_global, ret_gain);
+
+    cur_res.coarse_integration_time = tmp_res.coarse_integration_time;
+    cur_res.analog_gain_code_global = tmp_res.analog_gain_code_global;
+}
+
+void
+AiqAeHandler::adjust_ae_limitation (ia_aiq_exposure_sensor_parameters &cur_res)
+{
+    ia_aiq_exposure_sensor_descriptor * desc = &_sensor_descriptor;
+    uint64_t exposure_min = this->_exposure_time_min;
+    uint64_t exposure_max = this->_exposure_time_max;
+    double analog_max = this->_max_analog_gain;
+    uint32_t min_coarse_value = 0, max_coarse_value = 0;
+
+    if (exposure_min) {
+        min_coarse_value =  _time_to_coarse_line (desc, exposure_min);
+        if (min_coarse_value < desc->coarse_integration_time_min)
+            min_coarse_value = desc->coarse_integration_time_min;
+        if (cur_res.coarse_integration_time < min_coarse_value)
+            cur_res.coarse_integration_time = min_coarse_value;
+    }
+    if (exposure_max) {
+        max_coarse_value =  _time_to_coarse_line (desc, (uint32_t)exposure_max);
+        if (max_coarse_value > (uint32_t)(desc->line_periods_per_field - desc->coarse_integration_time_max_margin))
+            max_coarse_value = desc->line_periods_per_field - desc->coarse_integration_time_max_margin;
+        if (cur_res.coarse_integration_time > max_coarse_value)
+            cur_res.coarse_integration_time = max_coarse_value;
+    }
+
+    if (analog_max >= 1.0) {
+        /* limit gains */
+        double gain = _imx185_sensor_gain_code_to_mutiplier (cur_res.analog_gain_code_global);
+        if (gain > analog_max)
+            cur_res.analog_gain_code_global = _mutiplier_to_imx185_sensor_gain_code (analog_max);
+    }
+}
+
+XCamFlickerMode
+AiqAeHandler::get_flicker_mode ()
+{
+    {
+        AnalyzerHandler::HanlderLock lock(this);
+    }
+    return AeHandler::get_flicker_mode ();
+}
+
+int64_t
+AiqAeHandler::get_current_exposure_time ()
+{
+    AnalyzerHandler::HanlderLock lock(this);
+
+    return (int64_t)_result.aiq_exp_param.exposure_time_us;
+}
+
+double
+AiqAeHandler::get_current_analog_gain ()
+{
+    AnalyzerHandler::HanlderLock lock(this);
+    return (double)_result.aiq_exp_param.analog_gain;
+}
+
+double
+AiqAeHandler::get_max_analog_gain ()
+{
+    {
+        AnalyzerHandler::HanlderLock lock(this);
+    }
+    return AeHandler::get_max_analog_gain ();
+}
+
+AiqAwbHandler::AiqAwbHandler (SmartPtr<AiqCompositor> &aiq_compositor)
+    : _aiq_compositor (aiq_compositor)
+    , _started (false)
+{
+    xcam_mem_clear (&_cct_range);
+    xcam_mem_clear (&_result);
+    xcam_mem_clear (&_history_result);
+    xcam_mem_clear (&_cct_range);
+    xcam_mem_clear (&_input);
+
+    _input.frame_use = aiq_compositor->get_frame_use ();
+    _input.scene_mode = ia_aiq_awb_operation_mode_auto;
+    _input.manual_cct_range = NULL;
+    _input.manual_white_coordinate = NULL;
+}
+
+XCamReturn
+AiqAwbHandler::analyze (X3aResultList &output)
+{
+    ia_aiq  *ia_handle = NULL;
+    ia_aiq_awb_results *awb_ret = NULL;
+    ia_err ia_error = ia_err_none;
+
+    XCAM_UNUSED (output);
+
+    AnalyzerHandler::HanlderLock lock(this);
+
+    if (!ensure_ia_parameters ()) {
+        XCAM_LOG_ERROR ("AIQ AE ensure ia parameters failed");
+        return XCAM_RETURN_ERROR_PARAM;
+    }
+
+    ia_handle = _aiq_compositor->get_handle ();
+    XCAM_ASSERT (ia_handle);
+    ia_error = ia_aiq_awb_run (ia_handle, &_input, &awb_ret);
+    XCAM_FAIL_RETURN (ERROR, ia_error == ia_err_none, XCAM_RETURN_ERROR_AIQ, "AIQ run AWB failed");
+
+    _result = *awb_ret;
+    if (!_started) {
+        _history_result = _result;
+        _started = true;
+    }
+    adjust_speed (_history_result);
+    _history_result = _result;
+
+    return XCAM_RETURN_NO_ERROR;
+}
+
+bool
+AiqAwbHandler::ensure_ia_parameters ()
+{
+    bool ret = true;
+
+    _input.frame_use = _aiq_compositor->get_frame_use ();
+    ret = ret && ensure_awb_mode ();
+    return ret;
+}
+
+bool
+AiqAwbHandler::ensure_awb_mode ()
+{
+    XCamAwbMode mode = get_mode_unlock();
+
+    _input.manual_cct_range = NULL;
+    _input.scene_mode = ia_aiq_awb_operation_mode_auto;
+
+    switch (mode) {
+    case XCAM_AWB_MODE_AUTO:
+        _input.scene_mode = ia_aiq_awb_operation_mode_auto;
+        break;
+    case XCAM_AWB_MODE_MANUAL:
+        if (this->_cct_min && this->_cct_max) {
+            _input.scene_mode = ia_aiq_awb_operation_mode_manual_cct_range;
+            _cct_range.max_cct = this->_cct_max;
+            _cct_range.min_cct = this->_cct_min;
+            _input.manual_cct_range = &_cct_range;
+        } else
+            _input.scene_mode = ia_aiq_awb_operation_mode_auto;
+        break;
+    case XCAM_AWB_MODE_DAYLIGHT:
+        _input.scene_mode = ia_aiq_awb_operation_mode_daylight;
+        break;
+    case XCAM_AWB_MODE_SUNSET:
+        _input.scene_mode = ia_aiq_awb_operation_mode_sunset;
+        break;
+    case XCAM_AWB_MODE_CLOUDY:
+        _input.scene_mode = ia_aiq_awb_operation_mode_partly_overcast;
+        break;
+    case XCAM_AWB_MODE_TUNGSTEN:
+        _input.scene_mode = ia_aiq_awb_operation_mode_incandescent;
+        break;
+    case XCAM_AWB_MODE_FLUORESCENT:
+        _input.scene_mode = ia_aiq_awb_operation_mode_fluorescent;
+        break;
+    case XCAM_AWB_MODE_WARM_FLUORESCENT:
+        _input.scene_mode = ia_aiq_awb_operation_mode_incandescent;
+        break;
+    case XCAM_AWB_MODE_SHADOW:
+        _input.scene_mode = ia_aiq_awb_operation_mode_fully_overcast;
+        break;
+    case XCAM_AWB_MODE_WARM_INCANDESCENT:
+        _input.scene_mode = ia_aiq_awb_operation_mode_incandescent;
+        break;
+    case XCAM_AWB_MODE_NOT_SET:
+        break;
+
+    default:
+        XCAM_LOG_ERROR ("unknown or unsupported AWB mode(%d)", mode);
+        return false;
+    }
+    return true;
+}
+
+void
+AiqAwbHandler::adjust_speed (const ia_aiq_awb_results &last_ret)
+{
+    _result.final_r_per_g =
+        _calculate_new_value_by_speed (
+            last_ret.final_r_per_g, _result.final_r_per_g, get_speed_unlock ());
+    _result.final_b_per_g =
+        _calculate_new_value_by_speed (
+            last_ret.final_b_per_g, _result.final_b_per_g, get_speed_unlock ());
+}
+
+XCamReturn
+AiqAfHandler::analyze (X3aResultList &output)
+{
+    // TODO
+    XCAM_UNUSED (output);
+    return XCAM_RETURN_NO_ERROR;
+}
+
+AiqCommonHandler::AiqCommonHandler (SmartPtr<AiqCompositor> &aiq_compositor)
+    : _aiq_compositor (aiq_compositor)
+    , _gbce_result (NULL)
+{
+}
+
+
+XCamReturn
+AiqCommonHandler::analyze (X3aResultList &output)
+{
+    ia_aiq  *ia_handle = NULL;
+    ia_aiq_gbce_results *gbce_result = NULL;
+    ia_err ia_error = ia_err_none;
+
+    XCAM_UNUSED (output);
+
+    AnalyzerHandler::HanlderLock lock(this);
+
+    if (has_gbce_unlock()) {
+        ia_aiq_gbce_input_params gbce_input;
+        xcam_mem_clear (&gbce_input);
+        gbce_input.gbce_level = ia_aiq_gbce_level_use_tuning;
+        gbce_input.frame_use = _aiq_compositor->get_frame_use ();
+        gbce_input.ev_shift = 0;  // Todo
+        ia_handle = _aiq_compositor->get_handle ();
+        XCAM_ASSERT (ia_handle);
+        ia_error = ia_aiq_gbce_run (ia_handle, &gbce_input, &gbce_result);
+
+        XCAM_FAIL_RETURN (ERROR, ia_error == ia_err_none, XCAM_RETURN_ERROR_AIQ, "AIQ run GBCE failed");
+
+        //TODO, need copy GBCE result out, not just assign
+        _gbce_result = gbce_result;
+    } else {
+        _gbce_result = NULL;
+    }
+    return XCAM_RETURN_NO_ERROR;
+}
+
+class CmcParser {
+public:
+    explicit CmcParser (ia_binary_data &cpf)
+    {
+        _cmc = ia_cmc_parser_init (&cpf);
+    }
+    ~CmcParser ()
+    {
+        if (_cmc)
+            ia_cmc_parser_deinit (_cmc);
+    }
+    ia_cmc_t *get() {
+        return _cmc;
+    }
+
+private:
+    ia_cmc_t *_cmc;
+};
+
+void
+AiqCompositor::convert_window_to_ia (const XCam3AWindow &window, ia_rectangle &ia_window)
+{
+    ia_rectangle source;
+    ia_coordinate_system source_system;
+    ia_coordinate_system target_system = {IA_COORDINATE_TOP, IA_COORDINATE_LEFT, IA_COORDINATE_BOTTOM, IA_COORDINATE_RIGHT};
+
+    source_system.left = 0;
+    source_system.top = 0;
+    source_system.right = this->_width;
+    source_system.bottom = this->_height;
+    XCAM_ASSERT (_width && _height);
+
+    source.left = window.x_start;
+    source.top = window.y_start;
+    source.right = window.x_end;
+    source.bottom = window.y_end;
+    ia_coordinate_convert_rect (&source_system, &source, &target_system, &ia_window);
+}
+
+AiqCompositor::AiqCompositor ()
+    : _ia_handle (NULL)
+    , _ia_mkn (NULL)
+    , _pa_result (NULL)
+    , _frame_use (ia_aiq_frame_use_video)
+    , _width (0)
+    , _height (0)
+{
+    xcam_mem_clear (&_frame_params);
+}
+
+AiqCompositor::~AiqCompositor ()
+{
+}
+
+bool
+AiqCompositor::open (ia_binary_data &cpf)
+{
+    CmcParser cmc (cpf);
+
+    _ia_mkn = ia_mkn_init (ia_mkn_cfg_compression, 32000, 100000);
+    _ia_handle =
+        ia_aiq_init (
+            &cpf, NULL, NULL,
+            MAX_STATISTICS_WIDTH, MAX_STATISTICS_HEIGHT,
+            1, //max_num_stats_in
+            cmc.get(),
+            _ia_mkn);
+
+    if (_ia_handle == NULL) {
+        XCAM_LOG_WARNING ("AIQ init failed");
+        return false;
+    }
+
+    _adaptor = new IaIspAdaptor22;
+    XCAM_ASSERT (_adaptor.ptr());
+    if (!_adaptor->init (&cpf, MAX_STATISTICS_WIDTH, MAX_STATISTICS_HEIGHT, cmc.get(), _ia_mkn)) {
+        XCAM_LOG_WARNING ("AIQ isp adaptor init failed");
+        return false;
+    }
+
+    _pa_result = NULL;
+
+    XCAM_LOG_DEBUG ("Aiq compositor opened");
+    return true;
+}
+
+void
+AiqCompositor::close ()
+{
+    _adaptor.release ();
+    if (_ia_handle) {
+        ia_aiq_deinit (_ia_handle);
+        _ia_handle = NULL;
+    }
+
+    if (_ia_mkn) {
+        ia_mkn_uninit (_ia_mkn);
+        _ia_mkn = NULL;
+    }
+
+    _ae_handler.release ();
+    _awb_handler.release ();
+    _af_handler.release ();
+    _common_handler.release ();
+
+    _pa_result = NULL;
+
+    XCAM_LOG_DEBUG ("Aiq compositor closed");
+}
+
+bool
+AiqCompositor::set_sensor_mode_data (struct atomisp_sensor_mode_data *sensor_mode)
+{
+    _frame_params.horizontal_crop_offset = sensor_mode->crop_horizontal_start;
+    _frame_params.vertical_crop_offset = sensor_mode->crop_vertical_start;
+    _frame_params.cropped_image_height = sensor_mode->crop_vertical_end - sensor_mode->crop_vertical_start + 1;
+    _frame_params.cropped_image_width = sensor_mode->crop_horizontal_end - sensor_mode->crop_horizontal_start + 1;
+
+    /* hard code to 254? */
+    _frame_params.horizontal_scaling_denominator = 254;
+    _frame_params.vertical_scaling_denominator = 254;
+
+    if ((_frame_params.cropped_image_width == 0) || (_frame_params.cropped_image_height == 0)) {
+        _frame_params.horizontal_scaling_numerator = 0;
+        _frame_params.vertical_scaling_numerator = 0;
+    } else {
+        _frame_params.horizontal_scaling_numerator =
+            sensor_mode->output_width * 254 * sensor_mode->binning_factor_x / _frame_params.cropped_image_width;
+        _frame_params.vertical_scaling_numerator =
+            sensor_mode->output_height * 254 * sensor_mode->binning_factor_y / _frame_params.cropped_image_height;
+    }
+
+    if (!_ae_handler->set_description (sensor_mode)) {
+        XCAM_LOG_WARNING ("AIQ set ae description failed");
+        return XCAM_RETURN_ERROR_AIQ;
+    }
+    return true;
+}
+
+bool
+AiqCompositor::set_3a_stats (SmartPtr<X3aIspStatistics> &stats)
+{
+    ia_aiq_statistics_input_params aiq_stats_input;
+    ia_aiq_rgbs_grid *rgbs_grids = NULL;
+    ia_aiq_af_grid *af_grids = NULL;
+
+    xcam_mem_clear (&aiq_stats_input);
+    aiq_stats_input.frame_timestamp = stats->get_timestamp();
+    aiq_stats_input.frame_id = stats->get_timestamp() + 1;
+    aiq_stats_input.rgbs_grids = (const ia_aiq_rgbs_grid **)&rgbs_grids;
+    aiq_stats_input.num_rgbs_grids = 1;
+    aiq_stats_input.af_grids = (const ia_aiq_af_grid **)(&af_grids);
+    aiq_stats_input.num_af_grids = 1;
+
+    aiq_stats_input.frame_af_parameters = NULL;
+    aiq_stats_input.external_histograms = NULL;
+    aiq_stats_input.num_external_histograms = 0;
+    aiq_stats_input.camera_orientation = ia_aiq_camera_orientation_unknown;
+
+    if (_pa_result)
+        aiq_stats_input.frame_pa_parameters = _pa_result;
+    if (_ae_handler->is_started())
+        aiq_stats_input.frame_ae_parameters = _ae_handler->get_result ();
+    //if (_awb_handler->is_started())
+    //    aiq_stats_input.frame_awb_parameters = _awb_handler->get_result();
+
+    if (!_adaptor->convert_statistics (stats->get_3a_stats(), &rgbs_grids, &af_grids)) {
+        XCAM_LOG_WARNING ("ia isp adaptor convert 3a stats failed");
+        return false;
+    }
+
+    XCAM_LOG_DEBUG ("statistics grid info, width:%u, height:%u, blk_r:%u, blk_b:%u, blk_gr:%u, blk_gb:%u",
+                    aiq_stats_input.rgbs_grids[0]->grid_width,
+                    aiq_stats_input.rgbs_grids[0]->grid_height,
+                    aiq_stats_input.rgbs_grids[0]->blocks_ptr->avg_r,
+                    aiq_stats_input.rgbs_grids[0]->blocks_ptr->avg_b,
+                    aiq_stats_input.rgbs_grids[0]->blocks_ptr->avg_gr,
+                    aiq_stats_input.rgbs_grids[0]->blocks_ptr->avg_gb);
+
+    if (ia_aiq_statistics_set(get_handle (), &aiq_stats_input) != ia_err_none) {
+        XCAM_LOG_ERROR ("Aiq set statistic failed");
+        return false;
+    }
+    return true;
+}
+
+XCamReturn AiqCompositor::integrate (X3aResultList &results)
+{
+    IspInputParameters isp_params;
+    ia_aiq_pa_input_params pa_input;
+    ia_aiq_pa_results *pa_result = NULL;
+    ia_err ia_error = ia_err_none;
+    ia_binary_data output;
+    AiqAeHandler *aiq_ae = _ae_handler.ptr();
+    AiqAwbHandler *aiq_awb = _awb_handler.ptr();
+    AiqAfHandler *aiq_af = _af_handler.ptr();
+    AiqCommonHandler *aiq_common = _common_handler.ptr();
+    struct atomisp_parameters *isp_3a_result = NULL;
+    SmartPtr<X3aResult> isp_results;
+
+    XCAM_FAIL_RETURN (
+        ERROR,
+        aiq_ae && aiq_awb && aiq_af && aiq_common,
+        XCAM_RETURN_ERROR_PARAM,
+        "handlers are not AIQ inherited");
+
+    xcam_mem_clear (&pa_input);
+    pa_input.frame_use = _frame_use;
+    pa_input.awb_results = aiq_awb->get_result ();
+    if (aiq_ae->is_started())
+        pa_input.exposure_params = (aiq_ae->get_result ())->exposures[0].exposure;
+    pa_input.sensor_frame_params = &_frame_params;
+    pa_input.color_gains = NULL;
+
+    ia_error = ia_aiq_pa_run (_ia_handle, &pa_input, &pa_result);
+    if (ia_error != ia_err_none) {
+        XCAM_LOG_WARNING ("AIQ pa run failed"); // but not return error
+    }
+    _pa_result = pa_result;
+
+    isp_params.frame_use = _frame_use;
+    isp_params.awb_results = aiq_awb->get_result ();
+    if (aiq_ae->is_started())
+        isp_params.exposure_results = (aiq_ae->get_result ())->exposures[0].exposure;
+    isp_params.gbce_results = aiq_common->get_gbce_result ();
+    isp_params.sensor_frame_params = &_frame_params;
+    isp_params.pa_results = pa_result;
+
+    isp_params.manual_brightness = (int8_t)(aiq_common->get_brightness_unlock() * 128.0);
+    isp_params.manual_contrast = (int8_t)(aiq_common->get_contrast_unlock() * 128.0);
+    isp_params.manual_saturation = (int8_t)(aiq_common->get_saturation_unlock() * 128.0);
+    isp_params.manual_hue = (int8_t)(aiq_common->get_hue_unlock() * 128.0);
+    isp_params.manual_sharpness = (int8_t)(aiq_common->get_sharpness_unlock() * 128.0);
+    isp_params.manual_nr_level = (int8_t)(aiq_common->get_nr_level_unlock() * 128.0);
+
+    xcam_mem_clear (&output);
+    if (!_adaptor->run (&isp_params, &output)) {
+        XCAM_LOG_ERROR("Aiq to isp adaptor running failed");
+        return XCAM_RETURN_ERROR_ISP;
+    }
+    isp_3a_result = ((struct atomisp_parameters *)output.data);
+    isp_results = generate_3a_configs (isp_3a_result);
+    results.push_back (isp_results);
+    return XCAM_RETURN_NO_ERROR;
+}
+
+SmartPtr<X3aResult>
+AiqCompositor::generate_3a_configs (struct atomisp_parameters *parameters)
+{
+    SmartPtr<X3aResult> ret;
+
+    X3aAtomIspParametersResult *x3a_result =
+        new X3aAtomIspParametersResult (XCAM_IMAGE_PROCESS_ONCE);
+    x3a_result->set_isp_config (*parameters);
+    ret = x3a_result;
+    return ret;
+}
+
+void
+AiqCompositor::set_ae_handler (SmartPtr<AiqAeHandler> &handler)
+{
+    XCAM_ASSERT (!_ae_handler.ptr());
+    _ae_handler = handler;
+}
+
+void
+AiqCompositor::set_awb_handler (SmartPtr<AiqAwbHandler> &handler)
+{
+    XCAM_ASSERT (!_awb_handler.ptr());
+    _awb_handler = handler;
+}
+
+void
+AiqCompositor::set_af_handler (SmartPtr<AiqAfHandler> &handler)
+{
+    XCAM_ASSERT (!_af_handler.ptr());
+    _af_handler = handler;
+}
+
+void
+AiqCompositor::set_common_handler (SmartPtr<AiqCommonHandler> &handler)
+{
+    XCAM_ASSERT (!_common_handler.ptr());
+    _common_handler = handler;
+}
+
+
+};
diff --git a/xcore/aiq_handler.h b/xcore/aiq_handler.h
new file mode 100644
index 0000000..e78db94
--- /dev/null
+++ b/xcore/aiq_handler.h
@@ -0,0 +1,284 @@
+/*
+ * aiq_handler.h - AIQ handler
+ *
+ *  Copyright (c) 2014-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: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#ifndef XCAM_AIQ_HANDLER_H
+#define XCAM_AIQ_HANDLER_H
+
+#include "xcam_common.h"
+#include "xcam_defs.h"
+#include "xcam_utils.h"
+#include "handler_interface.h"
+#include "x3a_statistics_queue.h"
+#include "ia_types.h"
+#include "ia_aiq_types.h"
+#include "ia_cmc_parser.h"
+#include "ia_mkn_encoder.h"
+#include "ia_aiq.h"
+#include "ia_coordinate.h"
+
+typedef struct ia_isp_t ia_isp;
+
+namespace XCam {
+
+class AiqCompositor;
+struct IspInputParameters;
+
+class IaIspAdaptor {
+public:
+    explicit IaIspAdaptor()
+        : _handle (NULL)
+    {}
+    virtual ~IaIspAdaptor() {}
+
+    virtual bool init (
+        const ia_binary_data *cpf,
+        unsigned int max_width,
+        unsigned int max_height,
+        ia_cmc_t *cmc,
+        ia_mkn *mkn) = 0;
+    virtual bool convert_statistics (
+        void *statistics,
+        ia_aiq_rgbs_grid **out_rgbs_grid,
+        ia_aiq_af_grid **out_af_grid) = 0;
+    virtual bool run (
+        const IspInputParameters *isp_input_params,
+        ia_binary_data *output_data) = 0;
+
+private:
+    XCAM_DEAD_COPY (IaIspAdaptor);
+
+protected:
+    ia_isp *_handle;
+};
+
+class AiqAeHandler
+    : public AeHandler
+{
+private:
+    struct AiqAeResult {
+        ia_aiq_ae_results                 ae_result;
+        ia_aiq_ae_exposure_result         ae_exp_ret;
+        ia_aiq_exposure_parameters        aiq_exp_param;
+        ia_aiq_exposure_sensor_parameters sensor_exp_param;
+        ia_aiq_hist_weight_grid           weight_grid;
+        ia_aiq_flash_parameters           flash_param;
+
+        AiqAeResult();
+        void copy (ia_aiq_ae_results *result);
+
+        XCAM_DEAD_COPY (AiqAeResult);
+    };
+
+public:
+    explicit AiqAeHandler (SmartPtr<AiqCompositor> &aiq_compositor);
+    ~AiqAeHandler () {}
+
+    bool is_started () const {
+        return _started;
+    }
+
+    bool set_description (struct atomisp_sensor_mode_data *sensor_mode_data);
+
+    ia_aiq_ae_results *get_result () {
+        return &_result.ae_result;
+    }
+
+    //virtual functions from AnalyzerHandler
+    virtual XCamReturn analyze (X3aResultList &output);
+
+    // virtual functions from AeHandler
+    virtual XCamFlickerMode get_flicker_mode ();
+    virtual int64_t get_current_exposure_time ();
+    virtual double get_current_analog_gain ();
+    virtual double get_max_analog_gain ();
+
+private:
+    bool ensure_ia_parameters ();
+    bool ensure_ae_mode ();
+    bool ensure_ae_metering_mode ();
+    bool ensure_ae_priority_mode ();
+    bool ensure_ae_flicker_mode ();
+    bool ensure_ae_manual ();
+    bool ensure_ae_ev_shift ();
+
+    void adjust_ae_speed (
+        ia_aiq_exposure_sensor_parameters &cur_res,
+        const ia_aiq_exposure_sensor_parameters &last_res, double ae_speed);
+    void adjust_ae_limitation (ia_aiq_exposure_sensor_parameters &cur_res);
+    bool manual_control_result (
+        ia_aiq_exposure_sensor_parameters &cur_res,
+        const ia_aiq_exposure_sensor_parameters &last_res);
+
+    SmartPtr<X3aResult> pop_result ();
+
+    static void convert_xcam_window_to_ia (const XCam3AWindow &window, ia_rectangle &ia_window);
+
+private:
+    XCAM_DEAD_COPY (AiqAeHandler);
+
+protected:
+    SmartPtr<AiqCompositor>           _aiq_compositor;
+    /* AIQ */
+    ia_rectangle                      _ia_ae_window;
+    ia_aiq_exposure_sensor_descriptor _sensor_descriptor;
+    ia_aiq_ae_manual_limits           _manual_limits;
+
+    ia_aiq_ae_input_params            _input;
+
+    /* result */
+    AiqAeResult                       _result;
+    uint32_t                          _calculate_period;
+    bool                              _started;
+};
+
+class AiqAwbHandler
+    : public AwbHandler
+{
+public:
+    explicit AiqAwbHandler (SmartPtr<AiqCompositor> &aiq_compositor);
+    ~AiqAwbHandler () {}
+
+    virtual XCamReturn analyze (X3aResultList &output);
+
+    ia_aiq_awb_results *get_result () {
+        return &_result;
+    }
+    bool is_started () const {
+        return _started;
+    }
+
+private:
+    bool ensure_ia_parameters ();
+    bool ensure_awb_mode ();
+    void adjust_speed (const ia_aiq_awb_results &last_ret);
+
+    XCAM_DEAD_COPY (AiqAwbHandler);
+
+protected:
+    SmartPtr<AiqCompositor>     _aiq_compositor;
+    /*aiq*/
+    ia_aiq_awb_input_params     _input;
+    ia_aiq_awb_manual_cct_range _cct_range;
+
+    ia_aiq_awb_results          _result;
+    ia_aiq_awb_results          _history_result;
+    bool                        _started;
+};
+
+class AiqAfHandler
+    : public AfHandler
+{
+public:
+    explicit AiqAfHandler (SmartPtr<AiqCompositor> &aiq_compositor)
+        : _aiq_compositor (aiq_compositor)
+    {}
+    ~AiqAfHandler () {}
+
+    virtual XCamReturn analyze (X3aResultList &output);
+
+private:
+    XCAM_DEAD_COPY (AiqAfHandler);
+
+protected:
+    SmartPtr<AiqCompositor>        _aiq_compositor;
+};
+
+class AiqCommonHandler
+    : public CommonHandler
+{
+public:
+    explicit AiqCommonHandler (SmartPtr<AiqCompositor> &aiq_compositor);
+    ~AiqCommonHandler () {}
+
+    virtual XCamReturn analyze (X3aResultList &output);
+    ia_aiq_gbce_results *get_gbce_result () {
+        return _gbce_result;
+    }
+
+private:
+    XCAM_DEAD_COPY (AiqCommonHandler);
+
+protected:
+    SmartPtr<AiqCompositor>     _aiq_compositor;
+    ia_aiq_gbce_results        *_gbce_result;
+};
+
+class AiqCompositor {
+public:
+    explicit AiqCompositor ();
+    ~AiqCompositor ();
+
+    void set_ae_handler (SmartPtr<AiqAeHandler> &handler);
+    void set_awb_handler (SmartPtr<AiqAwbHandler> &handler);
+    void set_af_handler (SmartPtr<AiqAfHandler> &handler);
+    void set_common_handler (SmartPtr<AiqCommonHandler> &handler);
+
+    void set_frame_use (ia_aiq_frame_use value) {
+        _frame_use = value;
+    }
+    void set_size (uint32_t width, uint32_t height) {
+        _width = width;
+        _height = height;
+    }
+    bool open (ia_binary_data &cpf);
+    void close ();
+
+    bool set_sensor_mode_data (struct atomisp_sensor_mode_data *sensor_mode);
+    bool set_3a_stats (SmartPtr<X3aIspStatistics> &stats);
+
+    ia_aiq  * get_handle () {
+        return _ia_handle;
+    }
+    ia_aiq_frame_use get_frame_use () const {
+        return _frame_use;
+    }
+
+    XCamReturn integrate (  X3aResultList &results);
+
+    SmartPtr<X3aResult> generate_3a_configs (struct atomisp_parameters *parameters);
+    void convert_window_to_ia (const XCam3AWindow &window, ia_rectangle &ia_window);
+
+private:
+
+    XCAM_DEAD_COPY (AiqCompositor);
+
+private:
+    SmartPtr<IaIspAdaptor>     _adaptor;
+    SmartPtr<AiqAeHandler>     _ae_handler;
+    SmartPtr<AiqAwbHandler>    _awb_handler;
+    SmartPtr<AiqAfHandler>     _af_handler;
+    SmartPtr<AiqCommonHandler> _common_handler;
+    ia_aiq                    *_ia_handle;
+    ia_mkn                    *_ia_mkn;
+    ia_aiq_pa_results         *_pa_result;
+    ia_aiq_frame_use           _frame_use;
+    ia_aiq_frame_params        _frame_params;
+
+    /*grids*/
+    ;
+
+    uint32_t                   _width;
+    uint32_t                   _height;
+
+};
+
+};
+
+#endif //XCAM_AIQ_HANDLER_H
diff --git a/xcore/atomisp_device.cpp b/xcore/atomisp_device.cpp
new file mode 100644
index 0000000..5e30e6c
--- /dev/null
+++ b/xcore/atomisp_device.cpp
@@ -0,0 +1,186 @@
+/*
+ * atomisp_device.cpp - atomisp device
+ *
+ *  Copyright (c) 2014-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: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#include "atomisp_device.h"
+#include "v4l2_buffer_proxy.h"
+#include <linux/v4l2-subdev.h>
+#if HAVE_LIBDRM
+#include <drm.h>
+#include <drm_mode.h>
+#include <xf86drm.h>
+#include <xf86drmMode.h>
+
+#define DEFAULT_DRM_DEVICE "i915"
+#endif
+
+namespace XCam {
+
+AtomispDevice::AtomispDevice (const char *name)
+    : V4l2Device (name)
+    , _drm_handle (-1)
+{
+}
+
+AtomispDevice::~AtomispDevice ()
+{
+#if HAVE_LIBDRM
+    if (_drm_handle > 0)
+        drmClose (_drm_handle);
+#endif
+}
+
+XCamReturn
+AtomispDevice::pre_set_format (struct v4l2_format &format)
+{
+    uint32_t fps_n = 0, fps_d = 0;
+    struct v4l2_subdev_format subdev_fmt;
+
+    // set framerate by subdev
+    this->get_framerate (fps_n, fps_d);
+    if (fps_n != 0 && fps_d != 0) {
+        struct v4l2_subdev_frame_interval frame_intvl;
+
+        xcam_mem_clear (&frame_intvl);
+        if (io_control (VIDIOC_SUBDEV_G_FRAME_INTERVAL, &frame_intvl) < 0) {
+            XCAM_LOG_WARNING ("atomisp device(%s) get framerate failed ", XCAM_STR (get_device_name()));
+        } else {
+            frame_intvl.interval.denominator = fps_n;
+            frame_intvl.interval.numerator = fps_d;
+            if (io_control (VIDIOC_SUBDEV_S_FRAME_INTERVAL, &frame_intvl) < 0) {
+                XCAM_LOG_WARNING ("atomisp device(%s) set framerate failed", XCAM_STR (get_device_name()));
+            }
+        }
+    }
+
+    xcam_mem_clear (&subdev_fmt);
+    subdev_fmt.pad = 0;
+    subdev_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+    subdev_fmt.format.width = format.fmt.pix.width + 32;
+    subdev_fmt.format.height = format.fmt.pix.height + 17;
+    subdev_fmt.format.code = V4L2_MBUS_FMT_SRGGB10_1X10; //depends on sensor V4L2_MBUS_FMT_UYVY8_1X16;
+    subdev_fmt.format.field = V4L2_FIELD_NONE;
+
+    if (io_control(VIDIOC_SUBDEV_S_FMT, &subdev_fmt) < 0) {
+        XCAM_LOG_ERROR ("atomisp device(%s) set subdev format failed", XCAM_STR (get_device_name()));
+        return XCAM_RETURN_ERROR_IOCTL;
+    }
+    return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+AtomispDevice::allocate_buffer (
+    SmartPtr<V4l2Buffer> &buf,
+    const struct v4l2_format &format,
+    const uint32_t index)
+{
+#if HAVE_LIBDRM
+    if (get_mem_type () == V4L2_MEMORY_DMABUF) {
+        buf = create_drm_buf (format, index);
+        if (!buf.ptr()) {
+            XCAM_LOG_WARNING ("atomisp device(%s) allocate buffer failed", XCAM_STR (get_device_name()));
+            return XCAM_RETURN_ERROR_MEM;
+        }
+        return XCAM_RETURN_NO_ERROR;
+    }
+#endif
+
+    return V4l2Device::allocate_buffer (buf, format, index);
+}
+
+#if HAVE_LIBDRM
+
+class DrmV4l2Buffer
+    : public V4l2Buffer
+{
+public:
+    explicit DrmV4l2Buffer (
+        uint32_t gem_handle,
+        const struct v4l2_buffer &buf,
+        const struct v4l2_format &format,
+        AtomispDevice *device
+    )
+        : V4l2Buffer (buf, format)
+        , _gem_handle (gem_handle)
+        , _device (device)
+    {}
+    ~DrmV4l2Buffer ();
+
+private:
+    uint32_t       _gem_handle;
+    AtomispDevice *_device;
+};
+
+DrmV4l2Buffer::~DrmV4l2Buffer ()
+{
+    XCAM_ASSERT (_device);
+    int handle = _device->get_drm_handle ();
+    if (handle > 0) {
+        struct drm_mode_destroy_dumb gem;
+        xcam_mem_clear (&gem);
+        gem.handle = _gem_handle;
+        xcam_device_ioctl (handle, DRM_IOCTL_MODE_DESTROY_DUMB, &gem);
+    }
+}
+
+
+SmartPtr<V4l2Buffer>
+AtomispDevice::create_drm_buf (const struct v4l2_format &format, const uint32_t index)
+{
+    struct drm_mode_create_dumb gem;
+    struct drm_prime_handle prime;
+    struct v4l2_buffer v4l2_buf;
+    int ret = 0;
+
+    xcam_mem_clear (&gem);
+    xcam_mem_clear (&prime);
+    xcam_mem_clear (&v4l2_buf);
+
+    if (_drm_handle < 0)
+        _drm_handle = drmOpen (DEFAULT_DRM_DEVICE, NULL);
+    if (_drm_handle < 0) {
+        XCAM_LOG_WARNING ("open drm device(%s) failed", DEFAULT_DRM_DEVICE);
+        return NULL;
+    }
+
+    gem.width = format.fmt.pix.bytesperline;
+    gem.height = format.fmt.pix.height;
+    gem.bpp = 8;
+    ret = xcam_device_ioctl (_drm_handle, DRM_IOCTL_MODE_CREATE_DUMB, &gem);
+    XCAM_ASSERT (ret >= 0);
+
+    prime.handle = gem.handle;
+    ret = xcam_device_ioctl (_drm_handle, DRM_IOCTL_PRIME_HANDLE_TO_FD, &prime);
+    if (ret < 0) {
+        XCAM_LOG_WARNING ("create drm failed on DRM_IOCTL_PRIME_HANDLE_TO_FD");
+        return NULL;
+    }
+
+    v4l2_buf.index = index;
+    v4l2_buf.type = get_capture_buf_type ();
+    v4l2_buf.memory = V4L2_MEMORY_DMABUF;
+    v4l2_buf.m.fd = prime.fd;
+    v4l2_buf.length = XCAM_MAX (format.fmt.pix.sizeimage, gem.size); // todo check gem.size and format.fmt.pix.length
+    XCAM_LOG_DEBUG ("create drm buffer size:%lld", gem.size);
+    return new DrmV4l2Buffer (gem.handle, v4l2_buf, format, this);
+}
+
+#endif
+
+};
diff --git a/xcore/atomisp_device.h b/xcore/atomisp_device.h
new file mode 100644
index 0000000..72f2479
--- /dev/null
+++ b/xcore/atomisp_device.h
@@ -0,0 +1,62 @@
+/*
+ * atomisp_device.h - atomisp device
+ *
+ *  Copyright (c) 2014-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: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#ifndef XCAM_ATOMISP_DEVICE_H
+#define XCAM_ATOMISP_DEVICE_H
+
+#include "xcam_common.h"
+#include "xcam_defs.h"
+#include "v4l2_device.h"
+
+namespace XCam {
+
+class AtomispDevice
+    : public V4l2Device
+{
+    friend class DrmV4l2Buffer;
+
+public:
+    explicit AtomispDevice (const char *name = NULL);
+    ~AtomispDevice ();
+
+protected:
+    virtual XCamReturn pre_set_format (struct v4l2_format &format);
+    virtual XCamReturn allocate_buffer (
+        SmartPtr<V4l2Buffer> &buf,
+        const struct v4l2_format &format,
+        const uint32_t index);
+
+private:
+    XCAM_DEAD_COPY (AtomispDevice);
+
+#if HAVE_LIBDRM
+    int get_drm_handle () const {
+        return _drm_handle;
+    }
+    SmartPtr<V4l2Buffer> create_drm_buf (const struct v4l2_format &format, const uint32_t index);
+#endif
+
+private:
+    int _drm_handle;
+};
+
+};
+
+#endif //XCAM_ATOMISP_DEVICE_H
diff --git a/xcore/device_manager.cpp b/xcore/device_manager.cpp
new file mode 100644
index 0000000..193350c
--- /dev/null
+++ b/xcore/device_manager.cpp
@@ -0,0 +1,337 @@
+/*
+ * device_manager.h - device manager
+ *
+ *  Copyright (c) 2014-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: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#include "device_manager.h"
+#include "poll_thread.h"
+#include "xcam_thread.h"
+#include "x3a_image_process_center.h"
+#include "x3a_analyzer_manager.h"
+#include "isp_image_processor.h"
+#include "isp_controller.h"
+#if HAVE_IA_AIQ
+#include "x3a_analyzer_aiq.h"
+#endif
+
+#define XCAM_FAILED_STOP(exp, msg, ...)                 \
+    if ((exp) != XCAM_RETURN_NO_ERROR) {                \
+        XCAM_LOG_ERROR (msg, ## __VA_ARGS__);           \
+        stop ();                                        \
+        return ret;                                     \
+    }
+
+namespace XCam {
+
+class MessageThread
+    : public Thread
+{
+public:
+    explicit MessageThread (DeviceManager *dev_manager)
+        : Thread ("MessageThread")
+        , _manager (dev_manager)
+    {}
+
+protected:
+    virtual bool loop ();
+
+    DeviceManager *_manager;
+};
+
+bool
+MessageThread::loop()
+{
+    XCamReturn ret = _manager->message_loop();
+    if (ret == XCAM_RETURN_NO_ERROR || ret == XCAM_RETURN_ERROR_TIMEOUT)
+        return true;
+
+    return false;
+}
+
+XCamMessage::XCamMessage (XCamMessageType type, int64_t timestamp, const char *message)
+    : timestamp (timestamp)
+    , msg_id (type)
+{
+    if (message)
+        this->msg = strdup (message);
+}
+
+XCamMessage::~XCamMessage ()
+{
+    if (msg)
+        xcam_free (msg);
+}
+
+DeviceManager::DeviceManager()
+    : _has_3a (true)
+    , _is_running (false)
+{
+    _3a_process_center = new X3aImageProcessCenter;
+    XCAM_LOG_DEBUG ("~DeviceManager construction");
+}
+
+DeviceManager::~DeviceManager()
+{
+    XCAM_LOG_DEBUG ("~DeviceManager destruction");
+}
+
+bool
+DeviceManager::set_capture_device (SmartPtr<V4l2Device> &device)
+{
+    if (is_running())
+        return false;
+
+    XCAM_ASSERT (device.ptr () && !_device.ptr ());
+    _device = device;
+    return true;
+}
+bool
+DeviceManager::set_event_device (SmartPtr<V4l2SubDevice> &device)
+{
+    if (is_running())
+        return false;
+
+    XCAM_ASSERT (device.ptr () && !_subdevice.ptr ());
+    _subdevice = device;
+    return true;
+}
+
+bool
+DeviceManager::set_isp_controller (SmartPtr<IspController> &controller)
+{
+    if (is_running())
+        return false;
+
+    XCAM_ASSERT (controller.ptr () && !_isp_controller.ptr ());
+    _isp_controller = controller;
+    return true;
+}
+
+bool
+DeviceManager::set_analyzer (SmartPtr<X3aAnalyzer> &analyzer)
+{
+    if (is_running())
+        return false;
+
+    XCAM_ASSERT (analyzer.ptr () && !_3a_analyzer.ptr ());
+    _3a_analyzer = analyzer;
+    return true;
+}
+
+bool
+DeviceManager::add_image_processor (SmartPtr<ImageProcessor> &processor)
+{
+    if (is_running())
+        return false;
+
+    XCAM_ASSERT (processor.ptr ());
+    return _3a_process_center->insert_processor (processor);
+}
+
+XCamReturn
+DeviceManager::start ()
+{
+    XCamReturn ret = XCAM_RETURN_NO_ERROR;
+
+    // start device
+    XCAM_ASSERT (_device->is_opened());
+    if (!_device.ptr() || !_device->is_opened()) {
+        XCAM_FAILED_STOP (ret = XCAM_RETURN_ERROR_FILE, "capture device not ready");
+    }
+    XCAM_FAILED_STOP (ret = _device->start(), "capture device start failed");
+
+    //start subdevice
+    XCAM_ASSERT (_subdevice->is_opened());
+    if (!_subdevice.ptr() || !_subdevice->is_opened()) {
+        XCAM_FAILED_STOP (ret = XCAM_RETURN_ERROR_FILE, "event device not ready");
+    }
+    XCAM_FAILED_STOP (ret = _subdevice->start(), "start event device failed");
+
+    //suppose _device and _subdevice already started
+    if (!_isp_controller.ptr ())
+        _isp_controller = new IspController (_device);
+    XCAM_ASSERT (_isp_controller.ptr());
+
+    if (_has_3a) {
+        // Initialize and start analyzer
+        uint32_t width = 0, height = 0;
+
+        if (!_3a_analyzer.ptr()) {
+            _3a_analyzer = X3aAnalyzerManager::instance()->create_analyzer();
+        }
+        if (!_3a_analyzer.ptr()) {
+            XCAM_FAILED_STOP (ret = XCAM_RETURN_ERROR_PARAM, "create analyzer failed");
+        }
+        _3a_analyzer->set_results_callback (this);
+
+        _device->get_size (width, height);
+        XCAM_FAILED_STOP (ret = _3a_analyzer->init (width, height), "initialize analyzer failed");
+
+        XCAM_FAILED_STOP (ret = _3a_analyzer->start (), "start analyzer failed");
+
+        // Initialize and start image processors
+        if (!_3a_process_center->has_processors()) {
+            // default processor
+            SmartPtr<ImageProcessor> default_processor = new IspImageProcessor (_isp_controller);
+            XCAM_ASSERT (default_processor.ptr ());
+            _3a_process_center->insert_processor (default_processor);
+        }
+
+        _3a_process_center->set_image_callback(this);
+        XCAM_FAILED_STOP (ret = _3a_process_center->start (), "3A process center start failed");
+
+    }
+
+    //Initialize and start poll thread
+    _poll_thread = new PollThread;
+    _poll_thread->set_capture_device (_device);
+    _poll_thread->set_event_device (_subdevice);
+    _poll_thread->set_isp_controller (_isp_controller);
+    _poll_thread->set_callback (this);
+
+    XCAM_FAILED_STOP (ret = _poll_thread->start(), "start poll failed");
+
+    _is_running = true;
+
+    XCAM_LOG_DEBUG ("Device manager started");
+    return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+DeviceManager::stop ()
+{
+    _is_running = false;
+
+    if (_poll_thread.ptr())
+        _poll_thread->stop ();
+
+    if (_3a_analyzer.ptr()) {
+        _3a_analyzer->stop ();
+        _3a_analyzer->deinit ();
+    }
+
+    if (_3a_process_center.ptr())
+        _3a_process_center->stop ();
+
+    _subdevice->stop ();
+    _device->stop ();
+
+    _isp_controller.release ();
+    _poll_thread.release ();
+
+    XCAM_LOG_DEBUG ("Device manager stopped");
+    return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+DeviceManager::poll_3a_stats_ready (SmartPtr<X3aIspStatistics> &stats)
+{
+    XCamReturn ret = XCAM_RETURN_NO_ERROR;
+    X3aResultList results;
+    XCAM_ASSERT (_3a_analyzer.ptr());
+
+    ret = _3a_analyzer->push_3a_stats (stats);
+    XCAM_FAIL_RETURN (ERROR,
+                      ret == XCAM_RETURN_NO_ERROR,
+                      ret,
+                      "analyze 3a statistics failed");
+
+    return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+DeviceManager::poll_dvs_stats_ready ()
+{
+    XCAM_ASSERT (false);
+    // TODO
+    return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+DeviceManager::poll_buffer_ready (SmartPtr<V4l2BufferProxy> &buf)
+{
+    if (_has_3a) {
+        SmartPtr<VideoBuffer> video_buf = buf;
+        if (_3a_process_center->put_buffer (video_buf) == false)
+            return XCAM_RETURN_ERROR_UNKNOWN;
+    }
+    return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+DeviceManager::poll_buffer_failed (int64_t timestamp, const char *msg)
+{
+    post_message (XCAM_MESSAGE_BUF_ERROR, timestamp, msg);
+    return XCAM_RETURN_NO_ERROR;
+}
+
+void
+DeviceManager::x3a_calculation_done (X3aAnalyzer *analyzer, X3aResultList &results)
+{
+    XCamReturn ret = _3a_process_center->put_3a_results (results);
+    if (ret != XCAM_RETURN_NO_ERROR && ret != XCAM_RETURN_BYPASS) {
+        XCAM_LOG_WARNING ("apply 3a results failed");
+        return;
+    }
+    AnalyzerCallback::x3a_calculation_done (analyzer, results);
+}
+
+void
+DeviceManager::x3a_calculation_failed (X3aAnalyzer *analyzer, int64_t timestamp, const char *msg)
+{
+    AnalyzerCallback::x3a_calculation_failed (analyzer, timestamp, msg);
+}
+
+void
+DeviceManager::process_buffer_done (ImageProcessor *processor, SmartPtr<VideoBuffer> &buf)
+{
+    ImageProcessCallback::process_buffer_done (processor, buf);
+    handle_buffer (buf);
+}
+
+void
+DeviceManager::process_buffer_failed (ImageProcessor *processor, SmartPtr<VideoBuffer> &buf)
+{
+    ImageProcessCallback::process_buffer_failed (processor, buf);
+}
+
+void
+DeviceManager::process_image_result_done (ImageProcessor *processor, SmartPtr<X3aResult> &result)
+{
+    ImageProcessCallback::process_image_result_done (processor, result);
+}
+
+void
+DeviceManager::post_message (XCamMessageType type, int64_t timestamp, const char *msg)
+{
+    SmartPtr<XCamMessage> new_msg = new XCamMessage (type, timestamp, msg);
+    _msg_queue.push (new_msg);
+}
+
+XCamReturn
+DeviceManager::message_loop ()
+{
+    const static int32_t msg_time_out = -1; //wait until wakeup
+    SmartPtr<XCamMessage> msg = _msg_queue.pop (msg_time_out);
+    if (!msg.ptr ())
+        return XCAM_RETURN_ERROR_THREAD;
+    handle_message (msg);
+    return XCAM_RETURN_NO_ERROR;
+}
+
+};
diff --git a/xcore/device_manager.h b/xcore/device_manager.h
new file mode 100644
index 0000000..5b1489b
--- /dev/null
+++ b/xcore/device_manager.h
@@ -0,0 +1,133 @@
+/*
+ * device_manager.h - device manager
+ *
+ *  Copyright (c) 2014-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: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#ifndef XCAM_DEVICE_MANAGER_H
+#define XCAM_DEVICE_MANAGER_H
+
+#include "xcam_common.h"
+#include "xcam_defs.h"
+#include "smartptr.h"
+#include "v4l2_device.h"
+#include "v4l2_buffer_proxy.h"
+#include "x3a_analyzer.h"
+#include "image_processor.h"
+#include "x3a_statistics_queue.h"
+#include "poll_thread.h"
+
+namespace XCam {
+
+enum XCamMessageType {
+    XCAM_MESSAGE_BUF_OK = 0,
+    XCAM_MESSAGE_BUF_ERROR,
+    XCAM_MESSAGE_STATS_OK,
+    XCAM_MESSAGE_STATS_ERROR,
+    XCAM_MESSAGE_3A_RESULTS_OK,
+    XCAM_MESSAGE_3A_RESULTS_ERROR,
+};
+
+struct XCamMessage {
+    int64_t          timestamp;
+    XCamMessageType  msg_id;
+    char            *msg;
+
+    XCamMessage (
+        XCamMessageType type,
+        int64_t timestamp = InvalidTimestamp,
+        const char *message = NULL);
+    ~XCamMessage ();
+};
+
+class MessageThread;
+class X3aImageProcessCenter;
+
+class DeviceManager
+    : public PollCallback
+    , public AnalyzerCallback
+    , public ImageProcessCallback
+{
+    friend class MessageThread;
+
+public:
+    DeviceManager();
+    virtual ~DeviceManager();
+
+    bool set_capture_device (SmartPtr<V4l2Device> &device);
+    bool set_event_device (SmartPtr<V4l2SubDevice> &device);
+    bool set_isp_controller (SmartPtr<IspController> &controller);
+    bool set_analyzer (SmartPtr<X3aAnalyzer> &analyzer);
+    bool add_image_processor (SmartPtr<ImageProcessor> &processor);
+
+    bool is_running () const {
+        return _is_running;
+    }
+    bool has_3a () const {
+        return _has_3a;
+    }
+
+    XCamReturn start ();
+    XCamReturn stop ();
+
+protected:
+    virtual void handle_message (SmartPtr<XCamMessage> &msg) = 0;
+    virtual void handle_buffer (SmartPtr<VideoBuffer> &buf) = 0;
+
+protected:
+    //virtual functions derived from PollCallback
+    virtual XCamReturn poll_buffer_ready (SmartPtr<V4l2BufferProxy> &buf);
+    virtual XCamReturn poll_buffer_failed (int64_t timestamp, const char *msg);
+    virtual XCamReturn poll_3a_stats_ready (SmartPtr<X3aIspStatistics> &stats);
+    virtual XCamReturn poll_dvs_stats_ready ();
+
+    //virtual functions derived from AnalyzerCallback
+    virtual void x3a_calculation_done (X3aAnalyzer *analyzer, X3aResultList &results);
+    virtual void x3a_calculation_failed (X3aAnalyzer *analyzer, int64_t timestamp, const char *msg);
+
+    //virtual functions derived from ImageProcessCallback
+    virtual void process_buffer_done (ImageProcessor *processor, SmartPtr<VideoBuffer> &buf);
+    virtual void process_buffer_failed (ImageProcessor *processor, SmartPtr<VideoBuffer> &buf);
+    virtual void process_image_result_done (ImageProcessor *processor, SmartPtr<X3aResult> &result);
+
+private:
+    void post_message (XCamMessageType type, int64_t timestamp, const char *msg);
+    XCamReturn message_loop ();
+
+    XCAM_DEAD_COPY (DeviceManager);
+
+protected:
+    SmartPtr<V4l2Device>             _device;
+    SmartPtr<V4l2SubDevice>          _subdevice;
+    SmartPtr<PollThread>             _poll_thread;
+    SmartPtr<IspController>          _isp_controller;
+
+    /* 3A calculation and image processing*/
+    bool                             _has_3a;
+    SmartPtr<X3aAnalyzer>            _3a_analyzer;
+    SmartPtr<X3aImageProcessCenter>  _3a_process_center;
+
+    /* msg queue */
+    SafeList<XCamMessage>            _msg_queue;
+    SmartPtr<MessageThread>          _msg_thread;
+
+    bool                             _is_running;
+};
+
+};
+
+#endif //XCAM_DEVICE_MANAGER_H
diff --git a/xcore/handler_interface.cpp b/xcore/handler_interface.cpp
new file mode 100644
index 0000000..6fdf586
--- /dev/null
+++ b/xcore/handler_interface.cpp
@@ -0,0 +1,455 @@
+/*
+ * handler_interface.cpp - handler interface
+ *
+ *  Copyright (c) 2014-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: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#include "handler_interface.h"
+
+namespace XCam {
+
+AeHandler::AeHandler()
+    : _mode (XCAM_AE_MODE_AUTO)
+    , _metering_mode ()
+    , _window ()
+    , _flicker_mode ()
+    , _speed (1.0)
+    , _exposure_time_min (UINT64_C(0))
+    , _exposure_time_max (UINT64_C(0))
+    , _max_analog_gain (0.0)
+    , _manual_exposure_time (UINT64_C (0))
+    , _manual_analog_gain (0.0)
+    , _aperture_fn (0.0)
+    , _ev_shift (0.0)
+{
+    _window.x_start = 0;
+    _window.y_start = 0;
+    _window.x_end = 0;
+    _window.y_end = 0;
+    _window.weight = 0;
+}
+
+bool
+AeHandler::set_mode (XCamAeMode mode)
+{
+    AnalyzerHandler::HanlderLock lock(this);
+    _mode = mode;
+
+    XCAM_LOG_DEBUG ("ae set mode [%d]", mode);
+    return true;
+}
+
+bool
+AeHandler::set_metering_mode (XCamAeMeteringMode mode)
+{
+    AnalyzerHandler::HanlderLock lock(this);
+    _metering_mode = mode;
+
+    XCAM_LOG_DEBUG ("ae set metering mode [%d]", mode);
+    return true;
+}
+
+bool
+AeHandler::set_window (XCam3AWindow *window)
+{
+    AnalyzerHandler::HanlderLock lock(this);
+    _window = *window;
+
+    XCAM_LOG_DEBUG ("ae set metering mode window [x:%d, y:%d, x_end:%d, y_end:%d, weight:%d]",
+                    window->x_start,
+                    window->y_start,
+                    window->x_end,
+                    window->y_end,
+                    window->weight);
+    return true;
+}
+
+bool
+AeHandler::set_ev_shift (double ev_shift)
+{
+    AnalyzerHandler::HanlderLock lock(this);
+    _ev_shift = ev_shift;
+
+    XCAM_LOG_DEBUG ("ae set ev shift:%.03f", ev_shift);
+    return true;
+}
+
+bool
+AeHandler::set_speed (double speed)
+{
+    AnalyzerHandler::HanlderLock lock(this);
+    _speed = speed;
+
+    XCAM_LOG_DEBUG ("ae set speed:%.03f", speed);
+    return true;
+}
+
+bool
+AeHandler::set_flicker_mode (XCamFlickerMode flicker)
+{
+    AnalyzerHandler::HanlderLock lock(this);
+    _flicker_mode = flicker;
+
+    XCAM_LOG_DEBUG ("ae set flicker:%d", flicker);
+    return true;
+}
+
+XCamFlickerMode
+AeHandler::get_flicker_mode ()
+{
+    AnalyzerHandler::HanlderLock lock(this);
+    return _flicker_mode;
+}
+
+int64_t
+AeHandler::get_current_exposure_time ()
+{
+    AnalyzerHandler::HanlderLock lock(this);
+    if (_mode == XCAM_AE_MODE_MANUAL)
+        return _manual_exposure_time;
+    return INT64_C(-1);
+}
+
+double
+AeHandler::get_current_analog_gain ()
+{
+    AnalyzerHandler::HanlderLock lock(this);
+    if (_mode == XCAM_AE_MODE_MANUAL)
+        return _manual_analog_gain;
+    return 0.0;
+}
+
+bool
+AeHandler::set_manual_exposure_time (int64_t time_in_us)
+{
+    AnalyzerHandler::HanlderLock lock(this);
+    _manual_exposure_time = time_in_us;
+
+    XCAM_LOG_DEBUG ("ae set manual exposure time: %lldus", time_in_us);
+    return true;
+}
+
+bool
+AeHandler::set_manual_analog_gain (double gain)
+{
+    AnalyzerHandler::HanlderLock lock(this);
+    _manual_analog_gain = gain;
+
+    XCAM_LOG_DEBUG ("ae set manual analog gain: %.03f", gain);
+    return true;
+}
+
+bool
+AeHandler::set_aperture (double fn)
+{
+    AnalyzerHandler::HanlderLock lock(this);
+    _aperture_fn = fn;
+
+    XCAM_LOG_DEBUG ("ae set aperture fn: %.03f", fn);
+    return true;
+}
+
+bool
+AeHandler::set_max_analog_gain (double max_gain)
+{
+    AnalyzerHandler::HanlderLock lock(this);
+    _max_analog_gain = max_gain;
+
+    XCAM_LOG_DEBUG ("ae set max analog_gain: %.03f", max_gain);
+    return true;
+}
+
+double AeHandler::get_max_analog_gain ()
+{
+    AnalyzerHandler::HanlderLock lock(this);
+    return _max_analog_gain;
+}
+
+bool AeHandler::set_exposure_time_range (int64_t min_time_in_us, int64_t max_time_in_us)
+{
+    AnalyzerHandler::HanlderLock lock(this);
+    _exposure_time_min = min_time_in_us;
+    _exposure_time_max = max_time_in_us;
+
+    XCAM_LOG_DEBUG ("ae set exposrue range[%lldus, %lldus]", min_time_in_us, max_time_in_us);
+    return true;
+}
+
+bool
+AeHandler::get_exposure_time_range (int64_t *min_time_in_us, int64_t *max_time_in_us)
+{
+    XCAM_ASSERT (min_time_in_us && max_time_in_us);
+
+    AnalyzerHandler::HanlderLock lock(this);
+    *min_time_in_us = _exposure_time_min;
+    *max_time_in_us = _exposure_time_max;
+
+    return true;
+}
+
+AwbHandler::AwbHandler()
+    : _mode (XCAM_AWB_MODE_AUTO)
+    , _speed (1.0)
+    , _cct_min (0)
+    , _cct_max (0)
+    , _gr_gain (0.0)
+    , _r_gain (0.0)
+    , _b_gain (0.0)
+    , _gb_gain (0.0)
+{}
+
+bool
+AwbHandler::set_mode (XCamAwbMode mode)
+{
+    AnalyzerHandler::HanlderLock lock(this);
+    _mode = mode;
+
+    XCAM_LOG_DEBUG ("awb set mode [%d]", mode);
+    return true;
+}
+
+bool
+AwbHandler::set_speed (double speed)
+{
+    XCAM_FAIL_RETURN (
+        ERROR,
+        (0.0 < speed) && (speed <= 1.0),
+        false,
+        "awb speed(%f) is out of range, suggest (0.0, 1.0]", speed);
+
+    AnalyzerHandler::HanlderLock lock(this);
+    _speed = speed;
+
+    XCAM_LOG_DEBUG ("awb set speed [%f]", speed);
+    return true;
+}
+
+bool
+AwbHandler::set_color_temperature_range (uint32_t cct_min, uint32_t cct_max)
+{
+    XCAM_FAIL_RETURN (
+        ERROR,
+        (cct_min <= cct_max),
+        false,
+        "awb set wrong cct(%u, %u) parameters", cct_min, cct_max);
+
+    AnalyzerHandler::HanlderLock lock(this);
+    _cct_min = cct_min;
+    _cct_max = cct_max;
+
+    XCAM_LOG_DEBUG ("awb set cct range [%u, %u]", cct_min, cct_max);
+    return true;
+}
+
+bool
+AwbHandler::set_manual_gain (double gr, double r, double b, double gb)
+{
+    XCAM_FAIL_RETURN (
+        ERROR,
+        gr >= 0.0 && r >= 0.0 && b >= 0.0 && gb >= 0.0,
+        false,
+        "awb manual gain value must >= 0.0");
+
+    AnalyzerHandler::HanlderLock lock(this);
+    _gr_gain = gr;
+    _r_gain = r;
+    _b_gain = b;
+    _gb_gain = gb;
+    XCAM_LOG_DEBUG ("awb set manual gain value(gr:%.03f, r:%.03f, b:%.03f, gb:%.03f)", gr, r, b, gb);
+    return true;
+}
+
+CommonHandler::CommonHandler()
+    : _is_manual_gamma (false)
+    , _nr_level (0.0)
+    , _tnr_level (0.0)
+    , _brightness (0.0)
+    , _contrast (0.0)
+    , _hue (0.0)
+    , _saturation (0.0)
+    , _sharpness (0.0)
+    , _enable_dvs (false)
+    , _enable_gbce (false)
+    , _enable_night_mode (false)
+{}
+
+bool CommonHandler::set_dvs (bool enable)
+{
+    AnalyzerHandler::HanlderLock lock(this);
+    _enable_dvs = enable;
+
+    XCAM_LOG_DEBUG ("common 3A enable dvs:%s", XCAM_BOOL2STR(enable));
+    return true;
+}
+
+bool
+CommonHandler::set_gbce (bool enable)
+{
+    AnalyzerHandler::HanlderLock lock(this);
+    _enable_gbce = enable;
+
+    XCAM_LOG_DEBUG ("common 3A enable gbce:%s", XCAM_BOOL2STR(enable));
+    return true;
+}
+
+bool
+CommonHandler::set_night_mode (bool enable)
+{
+    AnalyzerHandler::HanlderLock lock(this);
+    _enable_night_mode = enable;
+
+    XCAM_LOG_DEBUG ("common 3A enable night mode:%s", XCAM_BOOL2STR(enable));
+    return true;
+}
+
+/* Picture quality */
+bool
+CommonHandler::set_noise_reduction_level (double level)
+{
+    XCAM_FAIL_RETURN (
+        ERROR,
+        level >= -1.0 && level < 1.0,
+        false,
+        "set NR levlel(%.03f) out of range[-1.0, 1.0]", level);
+
+    AnalyzerHandler::HanlderLock lock(this);
+    _nr_level = level;
+
+    XCAM_LOG_DEBUG ("common 3A set NR level:%.03f", level);
+    return true;
+}
+
+bool
+CommonHandler::set_temporal_noise_reduction_level (double level)
+{
+    XCAM_FAIL_RETURN (
+        ERROR,
+        level >= -1.0 && level < 1.0,
+        false,
+        "set TNR levlel(%.03f) out of range[-1.0, 1.0]", level);
+
+    AnalyzerHandler::HanlderLock lock(this);
+    _tnr_level = level;
+
+    XCAM_LOG_DEBUG ("common 3A set TNR level:%.03f", level);
+    return true;
+}
+
+bool
+CommonHandler::set_manual_brightness (double level)
+{
+    XCAM_FAIL_RETURN (
+        ERROR,
+        level >= -1.0 && level < 1.0,
+        false,
+        "set brightness levlel(%.03f) out of range[-1.0, 1.0]", level);
+
+    AnalyzerHandler::HanlderLock lock(this);
+    _brightness = level;
+
+    XCAM_LOG_DEBUG ("common 3A set brightness level:%.03f", level);
+    return true;
+}
+
+bool CommonHandler::set_manual_contrast (double level)
+{
+    XCAM_FAIL_RETURN (
+        ERROR,
+        level >= -1.0 && level < 1.0,
+        false,
+        "set contrast levlel(%.03f) out of range[-1.0, 1.0]", level);
+
+    AnalyzerHandler::HanlderLock lock(this);
+    _contrast = level;
+
+    XCAM_LOG_DEBUG ("common 3A set contrast level:%.03f", level);
+    return true;
+}
+
+bool CommonHandler::set_manual_hue (double level)
+{
+    XCAM_FAIL_RETURN (
+        ERROR,
+        level >= -1.0 && level < 1.0,
+        false,
+        "set hue levlel(%.03f) out of range[-1.0, 1.0]", level);
+
+    AnalyzerHandler::HanlderLock lock(this);
+    _hue = level;
+
+    XCAM_LOG_DEBUG ("common 3A set hue level:%.03f", level);
+    return true;
+}
+
+bool
+CommonHandler::set_manual_saturation (double level)
+{
+    XCAM_FAIL_RETURN (
+        ERROR,
+        level >= -1.0 && level < 1.0,
+        false,
+        "set saturation levlel(%.03f) out of range[-1.0, 1.0]", level);
+
+    AnalyzerHandler::HanlderLock lock(this);
+    _saturation = level;
+
+    XCAM_LOG_DEBUG ("common 3A set saturation level:%.03f", level);
+    return true;
+}
+
+bool CommonHandler::set_manual_sharpness (double level)
+{
+    XCAM_FAIL_RETURN (
+        ERROR,
+        level >= -1.0 && level < 1.0,
+        false,
+        "set sharpness levlel(%.03f) out of range[-1.0, 1.0]", level);
+
+    AnalyzerHandler::HanlderLock lock(this);
+    _sharpness = level;
+
+    XCAM_LOG_DEBUG ("common 3A set sharpness level:%.03f", level);
+    return true;
+}
+
+bool
+CommonHandler::set_gamma_table (double *r_table, double *g_table, double *b_table)
+{
+    AnalyzerHandler::HanlderLock lock(this);
+    if (!r_table && ! g_table && !b_table) {
+        _is_manual_gamma = false;
+        XCAM_LOG_DEBUG ("common 3A disabled gamma");
+        return true;
+    }
+
+    if (!r_table || !g_table || !b_table) {
+        XCAM_LOG_ERROR ("common 3A gamma table parameters wrong");
+        return false;
+    }
+
+    for (uint32_t i = 0; i < XCAM_GAMMA_TABLE_SIZE; ++i) {
+        _r_gamma [i] = r_table [i];
+        _g_gamma [i] = g_table [i];
+        _b_gamma [i] = b_table [i];
+    }
+    _is_manual_gamma = true;
+
+    XCAM_LOG_DEBUG ("common 3A enabled RGB gamma");
+    return true;
+}
+
+};
diff --git a/xcore/handler_interface.h b/xcore/handler_interface.h
new file mode 100644
index 0000000..e200c4b
--- /dev/null
+++ b/xcore/handler_interface.h
@@ -0,0 +1,259 @@
+/*
+ * handler_interface.h - handler interface
+ *
+ *  Copyright (c) 2014-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: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#ifndef XCAM_HANDLER_INTERFACE_H
+#define XCAM_HANDLER_INTERFACE_H
+
+#include "xcam_common.h"
+#include "xcam_defs.h"
+#include "xcam_mutex.h"
+#include "xcam_utils.h"
+#include "x3a_result.h"
+#include "xcam_3a_types.h"
+
+namespace XCam {
+
+class AnalyzerHandler {
+    friend class HanlderLock;
+public:
+    explicit AnalyzerHandler() {}
+    virtual ~AnalyzerHandler () {}
+
+    virtual XCamReturn analyze (X3aResultList &output) = 0;
+
+protected:
+    class HanlderLock
+        : public SmartLock
+    {
+    public:
+        HanlderLock(AnalyzerHandler *handler)
+            : SmartLock (handler->_mutex)
+        {}
+        ~HanlderLock() {}
+    };
+
+    // members
+    Mutex _mutex;
+};
+
+class AeHandler
+    : public AnalyzerHandler
+{
+public:
+    explicit AeHandler();
+    virtual ~AeHandler() {}
+
+    bool set_mode (XCamAeMode mode);
+    bool set_metering_mode (XCamAeMeteringMode mode);
+    bool set_window (XCam3AWindow *window);
+    bool set_ev_shift (double ev_shift);
+    bool set_speed (double speed);
+    bool set_flicker_mode (XCamFlickerMode flicker);
+    bool set_manual_exposure_time (int64_t time_in_us);
+    bool set_manual_analog_gain (double gain);
+    bool set_aperture (double fn);
+    bool set_max_analog_gain (double max_gain);
+    bool set_exposure_time_range (int64_t min_time_in_us, int64_t max_time_in_us);
+    bool get_exposure_time_range (int64_t *min_time_in_us, int64_t *max_time_in_us);
+
+    //virtual functions
+    virtual XCamFlickerMode get_flicker_mode ();
+    virtual int64_t get_current_exposure_time ();
+    virtual double get_current_analog_gain ();
+    virtual double get_max_analog_gain ();
+
+protected:
+    XCamAeMode get_mode_unlock() const {
+        return _mode;
+    }
+    XCamAeMeteringMode get_metering_mode_unlock() const {
+        return _metering_mode;
+    }
+    const XCam3AWindow &get_window_unlock() const {
+        return _window;
+    }
+    XCamFlickerMode get_flicker_mode_unlock() const {
+        return _flicker_mode;
+    }
+    double get_speed_unlock() const {
+        return _speed;
+    }
+    double get_ev_shift_unlock() const {
+        return _ev_shift;
+    }
+
+private:
+    XCAM_DEAD_COPY (AeHandler);
+
+protected:
+    XCamAeMode              _mode;
+    XCamAeMeteringMode      _metering_mode;
+    XCam3AWindow            _window;
+    XCamFlickerMode         _flicker_mode;
+    double                  _speed;
+
+    /* exposure limitation */
+    uint64_t                _exposure_time_min, _exposure_time_max; // exposure time range
+    double                  _max_analog_gain;
+
+    /* exposure manual values */
+    uint64_t                _manual_exposure_time;
+    double                  _manual_analog_gain;
+
+    double                  _aperture_fn;
+
+    /*ev*/
+    double                  _ev_shift;
+};
+
+class AwbHandler
+    : public AnalyzerHandler
+{
+public:
+    explicit AwbHandler();
+    virtual ~AwbHandler() {}
+
+    bool set_mode (XCamAwbMode mode);
+    bool set_speed (double speed);
+    bool set_color_temperature_range (uint32_t cct_min, uint32_t cct_max);
+    bool set_manual_gain (double gr, double r, double b, double gb);
+
+protected:
+    XCamAwbMode get_mode_unlock() const {
+        return _mode;
+    }
+    double get_speed_unlock () const {
+        return _speed;
+    }
+
+private:
+    XCAM_DEAD_COPY (AwbHandler);
+
+protected:
+    XCamAwbMode             _mode;
+    double                  _speed;
+    uint32_t                _cct_min, _cct_max;
+    XCam3AWindow            _window;
+
+    /* manual gain */
+    double                  _gr_gain;
+    double                  _r_gain;
+    double                  _b_gain;
+    double                  _gb_gain;
+};
+
+class AfHandler
+    : public AnalyzerHandler
+{
+public:
+    explicit AfHandler() {}
+    virtual ~AfHandler() {}
+private:
+    XCAM_DEAD_COPY (AfHandler);
+
+protected:
+};
+
+class CommonHandler
+    : public AnalyzerHandler
+{
+public:
+    explicit CommonHandler();
+    virtual ~CommonHandler() {}
+
+    bool set_dvs (bool enable);
+    bool set_gbce (bool enable);
+    bool set_night_mode (bool enable);
+
+    /* Picture quality */
+    bool set_noise_reduction_level (double level);
+    bool set_temporal_noise_reduction_level (double level);
+    bool set_manual_brightness (double level);
+    bool set_manual_contrast (double level);
+    bool set_manual_hue (double level);
+    bool set_manual_saturation (double level);
+    bool set_manual_sharpness (double level);
+    bool set_gamma_table (double *r_table, double *g_table, double *b_table);
+
+public:
+    bool has_gbce_unlock () const {
+        return _enable_gbce;
+    }
+    bool has_dvs_unlock () const {
+        return _enable_dvs;
+    }
+    bool has_night_mode_unlock () const {
+        return _enable_night_mode;
+    }
+
+    double get_nr_level_unlock () const {
+        return _nr_level;
+    }
+    double get_tnr_level_unlock () const {
+        return _tnr_level;
+    }
+    double get_brightness_unlock () const {
+        return _brightness;
+    }
+    double get_contrast_unlock () const {
+        return _contrast;
+    }
+    double get_hue_unlock () const {
+        return _hue;
+    }
+    double get_saturation_unlock () const {
+        return _saturation;
+    }
+    double get_sharpness_unlock () const {
+        return _sharpness;
+    }
+
+private:
+    XCAM_DEAD_COPY (CommonHandler);
+
+protected:
+    /* R, G, B gamma table, size = XCAM_GAMMA_TABLE_SIZE */
+    bool                      _is_manual_gamma;
+    double                    _r_gamma [XCAM_GAMMA_TABLE_SIZE];
+    double                    _g_gamma [XCAM_GAMMA_TABLE_SIZE];
+    double                    _b_gamma [XCAM_GAMMA_TABLE_SIZE];
+
+    /*
+     * manual brightness, contrast, hue, saturation, sharpness
+     * -1.0 < value < 1.0
+     */
+    double                     _nr_level;
+    double                     _tnr_level;
+
+    double                     _brightness;
+    double                     _contrast;
+    double                     _hue;
+    double                     _saturation;
+    double                     _sharpness;
+
+    /* others */
+    bool                       _enable_dvs;
+    bool                       _enable_gbce;
+    bool                       _enable_night_mode;
+};
+
+};
+
+#endif // XCAM_HANDLER_INTERFACE_H
diff --git a/xcore/image_processor.cpp b/xcore/image_processor.cpp
new file mode 100644
index 0000000..ab33306
--- /dev/null
+++ b/xcore/image_processor.cpp
@@ -0,0 +1,231 @@
+/*
+ * image_processor.h - 3a image processor
+ *
+ *  Copyright (c) 2014-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: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#include "image_processor.h"
+#include "xcam_thread.h"
+
+namespace XCam {
+
+void
+ImageProcessCallback::process_buffer_done (ImageProcessor *processor, SmartPtr<VideoBuffer> &buf) {
+    XCAM_ASSERT (buf.ptr() && processor);
+
+    int64_t ts = buf->get_timestamp();
+    XCAM_UNUSED (ts);
+    XCAM_LOG_DEBUG (
+        "processor(%s) handled buffer(" XCAM_TIMESTAMP_FORMAT ") successfully",
+        XCAM_STR(processor->get_name()),
+        XCAM_TIMESTAMP_ARGS (ts));
+}
+
+void
+ImageProcessCallback::process_buffer_failed (ImageProcessor *processor, SmartPtr<VideoBuffer> &buf)
+{
+    XCAM_ASSERT (buf.ptr() && processor);
+
+    int64_t ts = buf->get_timestamp();
+    XCAM_UNUSED (ts);
+    XCAM_LOG_WARNING (
+        "processor(%s) handled buffer(" XCAM_TIMESTAMP_FORMAT ") failed",
+        XCAM_STR(processor->get_name()),
+        XCAM_TIMESTAMP_ARGS (ts));
+}
+
+void
+ImageProcessCallback::process_image_result_done (ImageProcessor *processor, SmartPtr<X3aResult> &result)
+{
+    XCAM_ASSERT (result.ptr() && processor);
+
+    int64_t ts = result->get_timestamp();
+    XCAM_UNUSED (ts);
+
+    XCAM_LOG_DEBUG (
+        "processor(%s) processed result(type:%d, timestamp:" XCAM_TIMESTAMP_FORMAT ") done",
+        XCAM_STR(processor->get_name()),
+        (int)result->get_type(),
+        XCAM_TIMESTAMP_ARGS (ts));
+}
+
+class ImageProcessorThread
+    : public Thread
+{
+public:
+    ImageProcessorThread (ImageProcessor *processor)
+        : Thread ("image_processor")
+        , _processor (processor)
+    {}
+    ~ImageProcessorThread () {}
+
+    virtual bool loop ();
+
+private:
+    ImageProcessor *_processor;
+};
+
+bool ImageProcessorThread::loop ()
+{
+    XCamReturn ret = _processor->buffer_process_loop ();
+    if (ret == XCAM_RETURN_NO_ERROR || ret == XCAM_RETURN_ERROR_TIMEOUT)
+        return true;
+    return false;
+}
+
+ImageProcessor::ImageProcessor (const char* name)
+    : _name (NULL)
+    , _callback (NULL)
+{
+    _processor_thread = new ImageProcessorThread (this);
+    if (name)
+        _name = strdup (name);
+}
+
+ImageProcessor::~ImageProcessor ()
+{
+    if (_name)
+        xcam_free (_name);
+}
+
+bool
+ImageProcessor::set_callback (ImageProcessCallback *callback)
+{
+    XCAM_ASSERT (!_callback);
+    _callback = callback;
+    return true;
+}
+
+XCamReturn
+ImageProcessor::start()
+{
+    if (!_processor_thread->start()) {
+        return XCAM_RETURN_ERROR_THREAD;
+    }
+    XCAM_LOG_INFO ("ImageProcessor(%s) started", XCAM_STR (_name));
+    return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+ImageProcessor::stop()
+{
+    _video_buf_queue.wakeup ();
+    _processor_thread->stop ();
+    XCAM_LOG_DEBUG ("ImageProcessor(%s) stopped", XCAM_STR (_name));
+    return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+ImageProcessor::push_buffer (SmartPtr<VideoBuffer> &buf)
+{
+    if (_video_buf_queue.push (buf))
+        return XCAM_RETURN_NO_ERROR;
+
+    XCAM_LOG_DEBUG ("processor push buffer failed");
+    return XCAM_RETURN_ERROR_UNKNOWN;
+}
+
+XCamReturn
+ImageProcessor::push_3a_results (X3aResultList &results)
+{
+    X3aResultList valid_results;
+    XCamReturn ret = XCAM_RETURN_NO_ERROR;
+
+    filter_valid_results (results, valid_results);
+    if (valid_results.empty())
+        return XCAM_RETURN_BYPASS;
+
+    ret = apply_3a_results (valid_results);
+
+    if (ret != XCAM_RETURN_NO_ERROR && ret != XCAM_RETURN_BYPASS) {
+        XCAM_LOG_WARNING ("processor(%s) apply results failed", XCAM_STR(get_name()));
+        return ret;
+    }
+
+    if (_callback) {
+        for (X3aResultList::iterator i_res = valid_results.begin();
+                i_res != valid_results.end(); ++i_res) {
+            SmartPtr<X3aResult> &res = *i_res;
+            _callback->process_image_result_done (this, res);
+        }
+    }
+
+    return ret;
+}
+
+XCamReturn
+ImageProcessor::push_3a_result (SmartPtr<X3aResult> &result)
+{
+    X3aResultList valid_results;
+    XCamReturn ret = XCAM_RETURN_NO_ERROR;
+
+    if (!can_process_result(result))
+        return XCAM_RETURN_BYPASS;
+
+    ret = apply_3a_result (result);
+
+    if (ret != XCAM_RETURN_NO_ERROR && ret != XCAM_RETURN_BYPASS) {
+        XCAM_LOG_WARNING ("processor(%s) apply result failed", XCAM_STR(get_name()));
+        return ret;
+    }
+
+    if (_callback) {
+        _callback->process_image_result_done (this, result);
+    }
+
+    return ret;
+}
+
+void
+ImageProcessor::filter_valid_results (X3aResultList &input, X3aResultList &valid_results)
+{
+    for (X3aResultList::iterator i_res = input.begin(); i_res != input.end(); ) {
+        SmartPtr<X3aResult> &res = *i_res;
+        if (can_process_result(res)) {
+            valid_results.push_back (res);
+            input.erase (i_res++);
+        } else
+            ++i_res;
+    }
+}
+
+XCamReturn ImageProcessor::buffer_process_loop ()
+{
+    XCamReturn ret = XCAM_RETURN_NO_ERROR;
+    SmartPtr<VideoBuffer> new_buf;
+    SmartPtr<VideoBuffer> buf = _video_buf_queue.pop();
+
+    if (!buf.ptr())
+        return XCAM_RETURN_ERROR_MEM;
+
+    ret = this->process_buffer (buf, new_buf);
+    if (ret != XCAM_RETURN_NO_ERROR) {
+        XCAM_LOG_DEBUG ("processing buffer failed");
+    }
+
+    if (_callback) {
+        if (ret == XCAM_RETURN_NO_ERROR)
+            _callback->process_buffer_done (this, new_buf);
+        else
+            _callback->process_buffer_failed (this, buf);
+    }
+
+    return XCAM_RETURN_NO_ERROR;
+}
+
+
+};
diff --git a/xcore/image_processor.h b/xcore/image_processor.h
new file mode 100644
index 0000000..777e8cc
--- /dev/null
+++ b/xcore/image_processor.h
@@ -0,0 +1,97 @@
+/*
+ * image_processor.h - 3a image processor
+ *
+ *  Copyright (c) 2014-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: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#ifndef XCAM_IMAGE_PROCESSOR_H
+#define XCAM_IMAGE_PROCESSOR_H
+
+#include "xcam_common.h"
+#include "xcam_defs.h"
+#include "xcam_utils.h"
+#include "video_buffer.h"
+#include "x3a_result.h"
+#include "smartptr.h"
+#include "safe_list.h"
+
+namespace XCam {
+
+class ImageProcessor;
+
+/* callback interface */
+class ImageProcessCallback {
+public:
+    ImageProcessCallback () {}
+    virtual ~ImageProcessCallback () {}
+    virtual void process_buffer_done (ImageProcessor *processor, SmartPtr<VideoBuffer> &buf);
+    virtual void process_buffer_failed (ImageProcessor *processor, SmartPtr<VideoBuffer> &buf);
+    virtual void process_image_result_done (ImageProcessor *processor, SmartPtr<X3aResult> &result);
+
+private:
+    XCAM_DEAD_COPY (ImageProcessCallback);
+};
+
+class ImageProcessorThread;
+
+/* base class, ImageProcessor */
+class ImageProcessor
+{
+    friend class ImageProcessorThread;
+
+    typedef SafeList<VideoBuffer> VideoBufQueue;
+
+public:
+    explicit ImageProcessor (const char* name);
+    virtual ~ImageProcessor ();
+
+    const char *get_name () const {
+        return _name;
+    }
+
+    bool set_callback (ImageProcessCallback *callback);
+    XCamReturn start();
+    XCamReturn stop ();
+
+    XCamReturn push_buffer (SmartPtr<VideoBuffer> &buf);
+    XCamReturn push_3a_results (X3aResultList &results);
+    XCamReturn push_3a_result (SmartPtr<X3aResult> &result);
+
+protected:
+    virtual bool can_process_result (SmartPtr<X3aResult> &result) = 0;
+    virtual XCamReturn apply_3a_results (X3aResultList &results) = 0;
+    virtual XCamReturn apply_3a_result (SmartPtr<X3aResult> &result) = 0;
+    // buffer runs in another thread
+    virtual XCamReturn process_buffer(SmartPtr<VideoBuffer> &input, SmartPtr<VideoBuffer> &output) = 0;
+
+private:
+    void filter_valid_results (X3aResultList &input, X3aResultList &valid_results);
+    XCamReturn buffer_process_loop ();
+
+private:
+    XCAM_DEAD_COPY (ImageProcessor);
+
+protected:
+    char                          *_name;
+    ImageProcessCallback          *_callback;
+    SmartPtr<ImageProcessorThread> _processor_thread;
+    VideoBufQueue                  _video_buf_queue;
+};
+
+};
+
+#endif //XCAM_IMAGE_PROCESSOR_H
diff --git a/xcore/isp_config_translator.cpp b/xcore/isp_config_translator.cpp
new file mode 100644
index 0000000..d370579
--- /dev/null
+++ b/xcore/isp_config_translator.cpp
@@ -0,0 +1,144 @@
+/*
+ * isp_config_translator.cpp - isp config translator
+ *
+ *  Copyright (c) 2014-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: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#include "isp_config_translator.h"
+#include <math.h>
+
+namespace XCam {
+
+static uint32_t
+_get_max_bits (double value)
+{
+    uint32_t max_int = 0;
+    uint32_t interger_bits = 0;
+
+    max_int = (uint32_t)value;
+    while (max_int) {
+        ++interger_bits;
+        max_int = (max_int >> 1);
+    }
+    return interger_bits;
+}
+
+IspConfigTranslator::IspConfigTranslator (SmartPtr<SensorDescriptor> &sensor)
+    : _sensor (sensor)
+{
+    XCAM_ASSERT (_sensor.ptr());
+}
+
+IspConfigTranslator::~IspConfigTranslator ()
+{
+}
+
+XCamReturn
+IspConfigTranslator::translate_white_balance (
+    const XCam3aResultWhiteBalance &from,
+    struct atomisp_wb_config &to)
+{
+    uint32_t interger_bits = 0;
+    double multiplier = 0.0;
+    double max_gain = XCAM_MAX (from.b_gain, from.r_gain);
+    max_gain = XCAM_MAX (max_gain, from.gr_gain);
+    max_gain = XCAM_MAX (max_gain, from.gb_gain);
+
+    interger_bits = _get_max_bits (max_gain);
+    multiplier = (double)(1 << (16 - interger_bits));
+    to.integer_bits = interger_bits;
+    to.gr = (uint32_t)(from.gr_gain * multiplier + 0.5);
+    to.r = (uint32_t)(from.r_gain * multiplier + 0.5);
+    to.b = (uint32_t)(from.b_gain * multiplier + 0.5);
+    to.gb = (uint32_t)(from.gb_gain * multiplier + 0.5);
+
+    return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+IspConfigTranslator::translate_black_level (
+    const XCam3aResultBlackLevel &from, struct atomisp_ob_config &to)
+{
+    double multiplier = (double)(1 << 16);
+
+    to.mode = atomisp_ob_mode_fixed;
+    to.level_gr = (uint32_t)(from.gr_level * multiplier + 0.5);
+    to.level_r = (uint32_t)(from.r_level * multiplier + 0.5);
+    to.level_b = (uint32_t)(from.b_level * multiplier + 0.5);
+    to.level_gb = (uint32_t)(from.gb_level * multiplier + 0.5);
+
+    return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+IspConfigTranslator::translate_color_matrix (
+    const XCam3aResultColorMatrix &from, struct atomisp_cc_config &to)
+{
+    double max_value = 0.0;
+    uint32_t interger_bits = 0;
+    double multiplier = 0.0;
+    bool have_minus = false;
+    uint32_t i = 0;
+
+    for (i = 0; i < XCAM_COLOR_MATRIX_SIZE; ++i) {
+        if (fabs(from.matrix [i]) > max_value)
+            max_value = fabs(from.matrix [i]);
+        if (from.matrix [i] < 0)
+            have_minus = true;
+    }
+    interger_bits = _get_max_bits (max_value);
+    if (have_minus)
+        ++interger_bits;
+
+    XCAM_ASSERT (interger_bits < 13);
+    to.fraction_bits = 13 - interger_bits;
+    multiplier = (double)(1 << (13 - interger_bits));
+    for (i = 0; i < XCAM_COLOR_MATRIX_SIZE; ++i) {
+        to.matrix[i] = (int32_t)(from.matrix [i] * multiplier);
+    }
+    return XCAM_RETURN_NO_ERROR;
+}
+
+
+XCamReturn
+IspConfigTranslator::translate_exposure (
+    const XCam3aResultExposure &from,
+    struct atomisp_exposure &to)
+{
+    uint32_t coarse_time = 0, fine_time = 0;
+    int32_t analog_code = 0, digital_code = 0;
+    if (!_sensor->is_ready ()) {
+        XCAM_LOG_WARNING ("translate exposure failed since sensor not ready");
+        return XCAM_RETURN_ERROR_SENSOR;
+    }
+    if (!_sensor->exposure_time_to_integration (from.exposure_time, coarse_time, fine_time)) {
+        XCAM_LOG_WARNING ("translate exposure time failed");
+        return XCAM_RETURN_ERROR_SENSOR;
+    }
+    to.integration_time[0] = coarse_time;
+    to.integration_time[1] = fine_time;
+
+    if (!_sensor->exposure_gain_to_code (from.analog_gain, from.digital_gain, analog_code, digital_code)) {
+        XCAM_LOG_WARNING ("translate exposure gain failed");
+        return XCAM_RETURN_ERROR_SENSOR;
+    }
+    to.gain[0] = analog_code;
+    to.gain[1] = digital_code;
+    return XCAM_RETURN_NO_ERROR;
+}
+
+};
diff --git a/xcore/isp_config_translator.h b/xcore/isp_config_translator.h
new file mode 100644
index 0000000..c24e9c3
--- /dev/null
+++ b/xcore/isp_config_translator.h
@@ -0,0 +1,60 @@
+/*
+ * isp_config_translator.h - isp config translator
+ *
+ *  Copyright (c) 2014-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: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#ifndef XCAM_ISP_CONFIG_TRANSLATOR_H
+#define XCAM_ISP_CONFIG_TRANSLATOR_H
+
+#include "xcam_common.h"
+#include "xcam_defs.h"
+#include "xcam_utils.h"
+#include "x3a_result.h"
+#include "sensor_descriptor.h"
+#include "smartptr.h"
+#include <linux/atomisp.h>
+
+namespace XCam {
+
+class IspConfigTranslator {
+public:
+    explicit IspConfigTranslator (SmartPtr<SensorDescriptor> &sensor);
+    ~IspConfigTranslator ();
+
+    XCamReturn translate_white_balance (const XCam3aResultWhiteBalance &from, struct atomisp_wb_config &to);
+    XCamReturn translate_black_level (const XCam3aResultBlackLevel &from, struct atomisp_ob_config &to);
+    XCamReturn translate_color_matrix (const XCam3aResultColorMatrix &from, struct atomisp_cc_config &to);
+    XCamReturn translate_exposure (const XCam3aResultExposure &from, struct atomisp_exposure &to);
+    XCamReturn translate_demosaicing (const X3aDemosaicResult &from, struct atomisp_de_config &to);
+    XCamReturn translate_defect_pixel (const XCam3aResultDefectPixel &from, struct atomisp_dp_config &to);
+    XCamReturn translate_noise_reduction (const XCam3aResultNoiseReduction &from, struct atomisp_nr_config &to);
+    XCamReturn translate_edge_enhancement (const XCam3aResultEdgeEnhancement &from, struct atomisp_ee_config &to);
+    XCamReturn translate_gamma_table (const XCam3aResultGammaTable &from, struct atomisp_gamma_table &to);
+    XCamReturn translate_macc (const XCam3aResultMaccMatrix &from, struct atomisp_macc_table &to);
+    XCamReturn translate_ctc (const XCam3aResultChromaToneControl &from, struct atomisp_ctc_table &to);
+
+private:
+    XCAM_DEAD_COPY (IspConfigTranslator);
+
+private:
+    SmartPtr<SensorDescriptor> _sensor;
+};
+
+}
+
+#endif //XCAM_ISP_CONFIG_TRANSLATOR_H
diff --git a/xcore/isp_controller.cpp b/xcore/isp_controller.cpp
new file mode 100644
index 0000000..96d21a8
--- /dev/null
+++ b/xcore/isp_controller.cpp
@@ -0,0 +1,128 @@
+/*
+ * isp_controller.cpp - isp controller
+ *
+ *  Copyright (c) 2014-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: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#include "isp_controller.h"
+#include "v4l2_device.h"
+#include "x3a_statistics_queue.h"
+#include "x3a_isp_config.h"
+
+#include <linux/atomisp.h>
+
+namespace XCam {
+
+IspController::IspController (SmartPtr<V4l2Device> & device)
+    : _device (device)
+{
+}
+IspController::~IspController ()
+{
+}
+
+XCamReturn
+IspController::get_sensor_mode_data (struct atomisp_sensor_mode_data &sensor_mode_data)
+{
+    if ( _device->io_control (ATOMISP_IOC_G_SENSOR_MODE_DATA, &sensor_mode_data) < 0) {
+        XCAM_LOG_WARNING (" get ISP sensor mode data failed");
+        return XCAM_RETURN_ERROR_IOCTL;
+    }
+    return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+IspController::get_isp_parameter (struct atomisp_parm &parameters)
+{
+    if ( _device->io_control (ATOMISP_IOC_G_ISP_PARM, &parameters) < 0) {
+        XCAM_LOG_WARNING (" get ISP parameters failed");
+        return XCAM_RETURN_ERROR_IOCTL;
+    }
+    return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+IspController::get_3a_statistics (SmartPtr<X3aIspStatistics> &stats)
+{
+    struct atomisp_3a_statistics *isp_stats = NULL;
+
+    XCAM_ASSERT (stats.ptr());
+    XCAM_FAIL_RETURN (WARNING, stats.ptr(),
+                      XCAM_RETURN_ERROR_PARAM, "stats empty");
+
+    isp_stats =  stats->get_3a_stats ();
+
+    if ( _device->io_control (ATOMISP_IOC_G_3A_STAT, isp_stats) < 0) {
+        XCAM_LOG_WARNING (" get 3a stats failed from ISP");
+        return XCAM_RETURN_ERROR_IOCTL;
+    }
+    return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+IspController::set_3a_config (X3aIspConfig *config)
+{
+    struct atomisp_parameters &isp_config = config->get_isp_configs ();
+    if ( _device->io_control (ATOMISP_IOC_S_PARAMETERS, &isp_config) < 0) {
+        XCAM_LOG_WARNING (" set 3a config failed to ISP");
+        return XCAM_RETURN_ERROR_IOCTL;
+    }
+
+    return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+IspController::set_3a_exposure (X3aIspExposureResult *res)
+{
+    const struct atomisp_exposure &exposure = res->get_isp_config ();
+    return set_3a_exposure (exposure);
+
+    return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+IspController::set_3a_exposure (const struct atomisp_exposure &exposure)
+{
+    if ( _device->io_control (ATOMISP_IOC_S_EXPOSURE, (struct atomisp_exposure*)(&exposure)) < 0) {
+        XCAM_LOG_WARNING (" set exposure result failed to device");
+        return XCAM_RETURN_ERROR_IOCTL;
+    }
+    XCAM_LOG_DEBUG ("isp set exposure result, integration_time:%d, gain code:%d",
+                    exposure.integration_time[0], exposure.gain[0]);
+
+    return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+IspController::set_3a_focus (const XCam3aResultFocus &focus)
+{
+    int position = focus.position;
+    struct v4l2_control control;
+
+    xcam_mem_clear (&control);
+    control.id = V4L2_CID_FOCUS_ABSOLUTE;
+    control.value = position;
+
+    if (_device->io_control (VIDIOC_S_CTRL, &control) < 0) {
+        XCAM_LOG_WARNING (" set focus result failed to device");
+        return XCAM_RETURN_ERROR_IOCTL;
+    }
+    return XCAM_RETURN_NO_ERROR;
+}
+
+
+};
diff --git a/xcore/isp_controller.h b/xcore/isp_controller.h
new file mode 100644
index 0000000..ba2ff84
--- /dev/null
+++ b/xcore/isp_controller.h
@@ -0,0 +1,55 @@
+/*
+ * isp_controller.h - isp controller
+ *
+ *  Copyright (c) 2014-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: Wind Yuan <feng.yuan@intel.com>
+ */
+#ifndef XCAM_ISP_CONTROLLER_H
+#define XCAM_ISP_CONTROLLER_H
+
+#include "x3a_isp_config.h"
+
+namespace XCam {
+
+class V4l2Device;
+class X3aIspStatistics;
+class X3aIspConfig;
+
+class IspController {
+public:
+    explicit IspController (SmartPtr<V4l2Device> & device);
+    ~IspController ();
+
+    XCamReturn get_sensor_mode_data (struct atomisp_sensor_mode_data &sensor_mode_data);
+    XCamReturn get_isp_parameter (struct atomisp_parm &parameters);
+
+    XCamReturn get_3a_statistics (SmartPtr<X3aIspStatistics> &stats);
+    XCamReturn set_3a_config (X3aIspConfig *config);
+    XCamReturn set_3a_exposure (X3aIspExposureResult *res);
+    XCamReturn set_3a_exposure (const struct atomisp_exposure &exposure);
+    XCamReturn set_3a_focus (const XCam3aResultFocus &focus);
+
+private:
+
+    XCAM_DEAD_COPY (IspController);
+
+private:
+    SmartPtr<V4l2Device> _device;
+};
+
+};
+
+#endif //XCAM_ISP_CONTROLLER_H
diff --git a/xcore/isp_image_processor.cpp b/xcore/isp_image_processor.cpp
new file mode 100644
index 0000000..43a9e7e
--- /dev/null
+++ b/xcore/isp_image_processor.cpp
@@ -0,0 +1,173 @@
+/*
+ * isp_image_processor.cpp - isp image processor
+ *
+ *  Copyright (c) 2014-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: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#include "isp_image_processor.h"
+#include "x3a_isp_config.h"
+#include "isp_controller.h"
+#include "isp_config_translator.h"
+
+namespace XCam {
+
+IspImageProcessor::IspImageProcessor (SmartPtr<IspController> &controller)
+    : ImageProcessor ("IspImageProcessor")
+    , _controller (controller)
+    , _3a_config (new X3aIspConfig)
+{
+    _sensor = new SensorDescriptor;
+    _translator = new IspConfigTranslator (_sensor);
+    XCAM_LOG_DEBUG ("IspImageProcessor construction");
+}
+
+IspImageProcessor::~IspImageProcessor ()
+{
+    XCAM_LOG_DEBUG ("~IspImageProcessor destruction");
+}
+
+XCamReturn
+IspImageProcessor::process_buffer(SmartPtr<VideoBuffer> &input, SmartPtr<VideoBuffer> &output)
+{
+    output = input;
+    return XCAM_RETURN_NO_ERROR;
+}
+
+bool
+IspImageProcessor::can_process_result (SmartPtr<X3aResult> &result)
+{
+    XCAM_ASSERT (result.ptr());
+    switch (result->get_type()) {
+    case X3aIspConfig::IspExposureParameters:
+    case X3aIspConfig::IspAllParameters:
+    case XCAM_3A_RESULT_WHITE_BALANCE:
+    case XCAM_3A_RESULT_EXPOSURE:
+    case XCAM_3A_RESULT_BLACK_LEVEL:
+    case XCAM_3A_RESULT_YUV2RGB_MATRIX:
+    case XCAM_3A_RESULT_RGB2YUV_MATRIX:
+        return true;
+    default:
+        return false;
+    }
+
+    return false;
+}
+
+XCamReturn
+IspImageProcessor::apply_3a_results (X3aResultList &results)
+{
+    XCamReturn ret = XCAM_RETURN_NO_ERROR;
+
+    if (results.empty())
+        return XCAM_RETURN_ERROR_PARAM;
+
+    // activate sensor to make translator work
+    if (!_sensor->is_ready()) {
+        struct atomisp_sensor_mode_data sensor_data;
+        xcam_mem_clear (&sensor_data);
+        if (_controller->get_sensor_mode_data(sensor_data) != XCAM_RETURN_NO_ERROR) {
+            XCAM_LOG_WARNING ("ispimageprocessor initiliaze sensor failed");
+        } else
+            _sensor->set_sensor_data (sensor_data);
+        XCAM_ASSERT (_sensor->is_ready());
+    }
+
+    if ((ret = merge_results (results)) != XCAM_RETURN_NO_ERROR) {
+        XCAM_LOG_WARNING ("merge 3a result to isp config failed");
+        return XCAM_RETURN_ERROR_UNKNOWN;
+    }
+
+    if ((ret = apply_exposure_result (results)) != XCAM_RETURN_NO_ERROR) {
+        XCAM_LOG_WARNING ("set 3a exposure to sensor failed");
+    }
+
+    // check _3a_config
+    XCAM_ASSERT (_3a_config.ptr());
+    XCAM_ASSERT (_controller.ptr());
+    ret = _controller->set_3a_config (_3a_config.ptr());
+    if (ret != XCAM_RETURN_NO_ERROR) {
+        XCAM_LOG_WARNING ("set 3a config to isp failed");
+    }
+    _3a_config->clear ();
+    return ret;
+}
+
+XCamReturn
+IspImageProcessor::apply_3a_result (SmartPtr<X3aResult> &result)
+{
+    XCamReturn ret = XCAM_RETURN_NO_ERROR;
+
+    X3aResultList results;
+    results.push_back (result);
+    ret = apply_3a_results (results);
+    return ret;
+}
+
+XCamReturn
+IspImageProcessor::merge_results (X3aResultList &results)
+{
+    if (results.empty())
+        return XCAM_RETURN_ERROR_PARAM;
+
+    for (X3aResultList::iterator iter = results.begin ();
+            iter != results.end ();)
+    {
+        SmartPtr<X3aResult> &x3a_result = *iter;
+        if (_3a_config->attach (x3a_result, _translator.ptr())) {
+            x3a_result->set_done (true);
+            results.erase (iter++);
+        } else
+            ++iter;
+    }
+    return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+IspImageProcessor::apply_exposure_result (X3aResultList &results)
+{
+    XCamReturn ret = XCAM_RETURN_NO_ERROR;
+
+    for (X3aResultList::iterator iter = results.begin ();
+            iter != results.end ();)
+    {
+        if ((*iter)->get_type() == X3aIspConfig::IspExposureParameters) {
+            X3aIspExposureResult *res = dynamic_cast<X3aIspExposureResult*> ((*iter).ptr());
+            if (!res || ((ret = _controller->set_3a_exposure (res)) != XCAM_RETURN_NO_ERROR)) {
+                XCAM_LOG_WARNING ("set 3a exposure to sensor failed");
+            }
+            res->set_done (true);
+            results.erase (iter++);
+        } else if ((*iter)->get_type() == XCAM_3A_RESULT_EXPOSURE) {
+            X3aExposureResult *res = dynamic_cast<X3aExposureResult*>((*iter).ptr());
+            struct atomisp_exposure isp_exposure;
+            xcam_mem_clear (&isp_exposure);
+            ret = _translator->translate_exposure (res->get_standard_result (), isp_exposure);
+            if (ret != XCAM_RETURN_NO_ERROR) {
+                XCAM_LOG_WARNING ("translate 3a exposure to sensor failed");
+            }
+            if ((ret = _controller->set_3a_exposure (isp_exposure)) != XCAM_RETURN_NO_ERROR) {
+                XCAM_LOG_WARNING ("set 3a exposure to sensor failed");
+            }
+            res->set_done (true);
+            results.erase (iter++);
+        } else
+            ++iter;
+    }
+    return XCAM_RETURN_NO_ERROR;
+}
+
+};
diff --git a/xcore/isp_image_processor.h b/xcore/isp_image_processor.h
new file mode 100644
index 0000000..d1339b4
--- /dev/null
+++ b/xcore/isp_image_processor.h
@@ -0,0 +1,65 @@
+/*
+ * isp_image_processor.h - isp image processor
+ *
+ *  Copyright (c) 2014-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: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#ifndef XCAM_ISP_IMAGE_PROCESSOR_H
+#define XCAM_ISP_IMAGE_PROCESSOR_H
+
+#include "xcam_common.h"
+#include "xcam_defs.h"
+#include "xcam_utils.h"
+#include "image_processor.h"
+
+namespace XCam {
+
+class X3aIspConfig;
+class IspController;
+class IspConfigTranslator;
+class SensorDescriptor;
+
+class IspImageProcessor
+    : public ImageProcessor
+{
+public:
+    explicit IspImageProcessor (SmartPtr<IspController> &controller);
+    virtual ~IspImageProcessor ();
+
+protected:
+    //derive from ImageProcessor
+    virtual bool can_process_result (SmartPtr<X3aResult> &result);
+    virtual XCamReturn apply_3a_results (X3aResultList &results);
+    virtual XCamReturn apply_3a_result (SmartPtr<X3aResult> &result);
+    virtual XCamReturn process_buffer (SmartPtr<VideoBuffer> &input, SmartPtr<VideoBuffer> &output);
+
+private:
+    XCamReturn merge_results (X3aResultList &results);
+    XCamReturn apply_exposure_result (X3aResultList &results);
+
+    XCAM_DEAD_COPY (IspImageProcessor);
+
+private:
+    SmartPtr<IspController>          _controller;
+    SmartPtr<SensorDescriptor>       _sensor;
+    SmartPtr<IspConfigTranslator>    _translator;
+    SmartPtr<X3aIspConfig>           _3a_config;
+};
+
+};
+
+#endif //XCAM_ISP_IMAGE_PROCESSOR_H
diff --git a/xcore/libtbd.c b/xcore/libtbd.c
new file mode 100644
index 0000000..6c86af6
--- /dev/null
+++ b/xcore/libtbd.c
@@ -0,0 +1,647 @@
+/*
+** Copyright 2012-2013 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.
+*/
+
+#include <stdbool.h> /* defines bool type */
+#include <stddef.h>  /* defines size_t */
+#include <stdint.h>  /* defines integer types with specified widths */
+#include <stdio.h>   /* defines FILE */
+#include <string.h>  /* defines memcpy and memset */
+
+#include "libtbd.h"  /* our own header file */
+
+/*!
+* \brief Debug messages.
+*/
+#ifdef __ANDROID__
+#define LOG_TAG "libtbd"
+#include <utils/Log.h>
+#define MSG_LOG(...) LOGD(__VA_ARGS__)
+#define MSG_ERR(...) LOGE(__VA_ARGS__)
+#else
+#include <stdio.h>
+#define MSG_LOG(...) fprintf(stdout, __VA_ARGS__); fprintf(stdout, "\n");
+#define MSG_ERR(...) fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n");
+#endif
+
+/*
+ * Checks the validity of the pointer
+ * param[in]    a_ptr             Pointer to be examined
+ * return                         True if pointer ok
+ */
+bool is_valid_pointer(void* a_ptr)
+{
+    if ((!a_ptr) || ((unsigned long)(a_ptr) % sizeof(uint32_t))) {
+        return false;
+    } else {
+        return true;
+    }
+}
+
+/*
+ * Calculates checksum for a data block.
+ * param[in]    a_data_ptr        Data from where to calculate the checksum
+ * param[in]    a_data_size       Size of the data
+ * return                         The checksum
+ */
+uint32_t get_checksum(void *a_data_ptr, size_t a_data_size)
+{
+    uint32_t *ptr32 = a_data_ptr;
+    int size32 = a_data_size / sizeof(uint32_t);
+
+    /* Simple checksum algorithm: summing up the data content
+     * as 32-bit numbers */
+    uint32_t checksum32 = 0;
+    if (size32) {
+        if (size32 & 0x01) {
+            checksum32 += *ptr32++;
+            size32 -= 1;
+        }
+        if (size32 & 0x02) {
+            checksum32 += *ptr32++;
+            checksum32 += *ptr32++;
+            size32 -= 2;
+        }
+        for (; size32 > 0; size32-=4) {
+            checksum32 += *ptr32++;
+            checksum32 += *ptr32++;
+            checksum32 += *ptr32++;
+            checksum32 += *ptr32++;
+        }
+    }
+
+    return checksum32;
+}
+
+/*
+ * Common subroutine to validate Tagged Binary Data container, without
+ * paying attention to checksum or data tagging. This function assumes
+ * that the data resides in "legal" memory area as there is no size
+ * given together with input pointer.
+ * param[in]    a_data_ptr        Pointer to container
+ * return                         Return code indicating possible errors
+ */
+tbd_error_t validate_anysize(void *a_data_ptr)
+{
+    uint8_t *byte_ptr, *eof_ptr;
+    tbd_record_header_t *record_ptr;
+    uint32_t record_size;
+
+    /* Container should begin with a header */
+    tbd_header_t *header_ptr = a_data_ptr;
+
+    /* Check against illegal pointers */
+    if (!is_valid_pointer(header_ptr)) {
+        MSG_ERR("LIBTBD ERROR: Cannot access data!");
+        return tbd_err_data;
+    }
+
+    /* Check that the indicated data size makes sense,
+     * and is not too much or too little */
+    if (header_ptr->size % sizeof(uint32_t)) {
+        MSG_ERR("LIBTBD ERROR: Size in header should be multiple of 4 bytes!");
+        return tbd_err_data;
+    }
+    if (header_ptr->size < sizeof(tbd_header_t)) {
+        MSG_ERR("LIBTBD ERROR: Invalid data header!");
+        return tbd_err_data;
+    }
+
+    /* First record is just after header, a byte pointer is needed
+     * to do math with sizes and pointers */
+    byte_ptr = (uint8_t *)(header_ptr + 1);
+    eof_ptr = (uint8_t *)(a_data_ptr) + header_ptr->size;
+
+    /* Loop until there are no more records to go */
+    while (byte_ptr < eof_ptr) {
+        /* At least one more record is expected */
+
+        /* Record header must be within the given data size */
+        if (byte_ptr + sizeof(tbd_record_header_t) > eof_ptr) {
+            MSG_ERR("LIBTBD ERROR: Invalid data header!");
+            return tbd_err_data;
+        }
+
+        record_ptr = (tbd_record_header_t *)(byte_ptr);
+        record_size = record_ptr->size;
+
+        /* Check that the indicated record size makes sense,
+         * and is not too much or too little */
+        if (record_size % sizeof(uint32_t)) {
+            MSG_ERR("LIBTBD ERROR: Size in record should be multiple of 4 bytes!");
+            return tbd_err_data;
+        }
+        if (record_size < sizeof(tbd_record_header_t)) {
+            MSG_ERR("LIBTBD ERROR: Invalid record header!");
+            return tbd_err_data;
+        }
+        if (byte_ptr + record_size > eof_ptr) {
+            MSG_ERR("LIBTBD ERROR: Invalid record header!");
+            return tbd_err_data;
+        }
+
+        /* This record ok, continue the while loop... */
+        byte_ptr += record_size;
+    }
+
+    /* Seems that we have a valid data with no more headers */
+    return tbd_err_none;
+}
+
+/*
+ * Common subroutine to validate Tagged Binary Data, without paying
+ * attention to checksum or data tagging. Also, this function does
+ * check that the data fits in the given buffer size.
+ * param[in]    a_data_ptr        Pointer to data buffer
+ * param[in]    a_data_size       Size of the data buffer
+ * return                         Return code indicating possible errors
+ */
+tbd_error_t validate(void *a_data_ptr, size_t a_data_size)
+{
+    /* Container should begin with a header */
+    tbd_header_t *header_ptr = a_data_ptr;
+
+    /* Check against illegal pointers */
+    if (!is_valid_pointer(header_ptr)) {
+        MSG_ERR("LIBTBD ERROR: Cannot access data!");
+        return tbd_err_data;
+    }
+
+    /* Check that the TBD header fits into given data */
+    if (sizeof(tbd_header_t) > a_data_size) {
+        MSG_ERR("TBD ERROR: #1 Too small data buffer given!");
+        return tbd_err_data;
+    }
+
+    /* Check that the indicated data fits in the buffer */
+    if (header_ptr->size > a_data_size) {
+        MSG_ERR("TBD ERROR: #2 Too small data buffer given!");
+        return tbd_err_data;
+    }
+
+    /* Check the the content is ok */
+    return validate_anysize(a_data_ptr);
+}
+
+/*
+ * Creates a new, empty Tagged Binary Data container with the tag
+ * that was given. Also updates the checksum and size accordingly.
+ * Note that the buffer size must be large enough for the header
+ * to fit in, the exact amount being 24 bytes (for tbd_header_t).
+ * param[in]    a_data_ptr        Pointer to modifiable container buffer
+ * param[in]    a_data_size       Size of the container buffer
+ * param[in]    a_tag             Tag the container shall have
+ * param[out]   a_new_size        Updated container size
+ * return                         Return code indicating possible errors
+ */
+tbd_error_t tbd_create(void *a_data_ptr, size_t a_data_size
+    , tbd_tag_t a_tag, size_t *a_new_size)
+{
+    tbd_header_t *header_ptr;
+
+    /* Check that the TBD header fits into given data */
+    if (sizeof(tbd_header_t) > a_data_size) {
+        MSG_ERR("LIBTBD ERROR: Not enough data given!");
+        return tbd_err_argument;
+    }
+
+    /* Nullify everything */
+    memset(a_data_ptr, 0, sizeof(tbd_header_t));
+
+    /* The header is what we need */
+    header_ptr = a_data_ptr;
+
+    header_ptr->tag = a_tag;
+
+    header_ptr->size = sizeof(tbd_header_t);
+    header_ptr->version = IA_TBD_VERSION;
+    header_ptr->revision = IA_TBD_REVISION;
+    header_ptr->config_bits = 0;
+    header_ptr->checksum = get_checksum(header_ptr, sizeof(tbd_header_t));
+
+    *a_new_size = sizeof(tbd_header_t);
+
+    return tbd_err_none;
+}
+
+/*
+ * Performs number of checks to given Tagged Binary Data container,
+ * including the verification of the checksum. The function does not
+ * care about the tag type of the container.
+ * param[in]    a_data_ptr        Pointer to container buffer
+ * param[in]    a_data_size       Size of the container buffer
+ * return                         Return code indicating possible errors
+ */
+tbd_error_t tbd_validate_anytag(void *a_data_ptr, size_t a_data_size)
+{
+    tbd_header_t *header_ptr;
+
+    /* Check the the content is ok */
+    int r;
+    if ((r = validate(a_data_ptr, a_data_size))) {
+        return r;
+    }
+
+    /* Container should begin with a header */
+    header_ptr = a_data_ptr;
+
+    /* Check that the checksum is correct */
+
+    /* When calculating the checksum for the original data, the checksum
+     * field has been filled with zero value - so after inserting the
+     * checksum in its place, the new calculated checksum is actually
+     * two times the original */
+
+    if (get_checksum(header_ptr, header_ptr->size) - header_ptr->checksum != header_ptr->checksum) {
+        MSG_ERR("LIBTBD ERROR: Checksum doesn't match!");
+        return tbd_err_data;
+    }
+
+    /* Seems that we have valid data */
+    return tbd_err_none;
+}
+
+/*
+ * Performs number of checks to given Tagged Binary Data container,
+ * including the verification of the checksum. Also, the data must have
+ * been tagged properly. The tag is further used to check endianness,
+ * and if it seems wrong, a specific debug message is printed out.
+ * param[in]    a_data_ptr        Pointer to container buffer
+ * param[in]    a_data_size       Size of the container buffer
+ * param[in]    a_tag             Tag the data must have
+ * return                         Return code indicating possible errors
+ */
+tbd_error_t tbd_validate(void *a_data_ptr, size_t a_data_size
+    , tbd_tag_t a_tag)
+{
+    tbd_header_t *header_ptr;
+
+    /* Check the the content is ok */
+    int r;
+    if ((r = validate(a_data_ptr, a_data_size))) {
+        return r;
+    }
+
+    /* Container should begin with a header */
+    header_ptr = a_data_ptr;
+
+    /* Check that the tag is correct */
+    if (header_ptr->tag != a_tag) {
+        /* See if we have wrong endianness or incorrect tag */
+        uint32_t reverse_tag = ( (((a_tag) >> 24) & 0x000000FF)
+            | (((a_tag) >> 8) & 0x0000FF00)
+            | (((a_tag) << 8) & 0x00FF0000)
+            | (((a_tag) << 24) & 0xFF000000) );
+
+        if (reverse_tag == header_ptr->tag) {
+            MSG_ERR("LIBTBD ERROR: Wrong endianness of data!");
+        } else {
+            MSG_ERR("LIBTBD ERROR: Data is not tagged properly!");
+        }
+        return tbd_err_data;
+    }
+
+    /* Check that the checksum is correct */
+
+    /* When calculating the checksum for the original data, the checksum
+     * field has been filled with zero value - so after inserting the
+     * checksum in its place, the new calculated checksum is actually
+     * two times the original */
+
+    if (get_checksum(header_ptr, header_ptr->size) - header_ptr->checksum != header_ptr->checksum) {
+        MSG_ERR("LIBTBD ERROR: Checksum doesn't match!");
+        return tbd_err_data;
+    }
+
+    /* Seems that we have valid data */
+    return tbd_err_none;
+}
+
+/*
+ * Checks if a given kind of record exists in the Tagged Binary Data,
+ * and if yes, tells the location of such record as well as its size.
+ * If there are multiple records that match the query, the indicated
+ * record is the first one.
+ * param[in]    a_data_ptr        Pointer to container buffer
+ * param[in]    a_record_class    Class the record must have
+ * param[in]    a_record_format   Format the record must have
+ * param[out]   a_record_data     Record data (or NULL if not found)
+ * param[out]   a_record_size     Record size (or 0 if not found)
+ * return                         Return code indicating possible errors
+ */
+tbd_error_t tbd_get_record(void *a_data_ptr
+    , tbd_class_t a_record_class, tbd_format_t a_record_format
+    , void **a_record_data, size_t *a_record_size)
+{
+    tbd_header_t *header_ptr;
+    uint8_t *byte_ptr, *eof_ptr;
+
+    /* Check the the content is ok */
+    int r;
+    if ((r = validate_anysize(a_data_ptr))) {
+        return r;
+    }
+
+    /* Container should begin with a header */
+    header_ptr = a_data_ptr;
+
+    /* First record is just after header */
+    byte_ptr = (uint8_t *)(header_ptr + 1);
+    eof_ptr = (uint8_t *)(a_data_ptr) + header_ptr->size;
+
+    /* Loop until there are no more records to go */
+    while (byte_ptr < eof_ptr) {
+        /* At least one more record is expected */
+        tbd_record_header_t *record_ptr = (tbd_record_header_t *)(byte_ptr);
+
+        uint16_t record_class = record_ptr->class_id;
+        uint8_t  record_format = record_ptr->format_id;
+        uint32_t record_size = record_ptr->size;
+
+        if (((a_record_class == tbd_class_any) || (a_record_class == record_class))
+            && ((a_record_format == tbd_format_any) || (a_record_format == record_format))) {
+
+            /* Match found */
+            *a_record_data = record_ptr + 1;
+            *a_record_size = record_size - sizeof(tbd_record_header_t);
+
+            return tbd_err_none;
+
+        }
+
+        /* Match not found yet, continue the while loop... */
+        byte_ptr += record_size;
+    }
+
+    MSG_LOG("libtbd: Record not found!");
+    *a_record_data = NULL;
+    *a_record_size = 0;
+    return tbd_err_none;
+}
+
+/*
+ * The given record is inserted into the Tagged Binary Data container
+ * that must exist already. New records are always added to the end,
+ * regardless if a record with the same class and format field already
+ * exists in the data. Also updates the checksum and size accordingly.
+ * Note that the buffer size must be large enough for the inserted
+ * record to fit in, the exact amount being the size of original
+ * Tagged Binary Data container plus the size of record data to be
+ * inserted plus 8 bytes (for tbd_record_header_t).
+ * param[in]    a_data_ptr        Pointer to modifiable container buffer
+ * param[in]    a_data_size       Size of buffer (surplus included)
+ * param[in]    a_record_class    Class the record shall have
+ * param[in]    a_record_format   Format the record shall have
+ * param[in]    a_record_data     Record data
+ * param[in]    a_record_size     Record size
+ * param[out]   a_new_size        Updated container size
+ * return                         Return code indicating possible errors
+ */
+tbd_error_t tbd_insert_record(void *a_data_ptr, size_t a_data_size
+    , tbd_class_t a_record_class, tbd_format_t a_record_format
+    , void *a_record_data, size_t a_record_size
+    , size_t *a_new_size)
+{
+    tbd_header_t *header_ptr;
+    size_t new_size;
+    tbd_record_header_t *record_ptr;
+    int r;
+
+    /* Check the the content is ok */
+    if ((r = validate(a_data_ptr, a_data_size))) {
+        return r;
+    }
+
+    /* Container should begin with a header */
+    header_ptr = a_data_ptr;
+
+    /* Check that the new record fits into given data */
+    new_size = header_ptr->size + sizeof(tbd_record_header_t) + a_record_size;
+
+    if (new_size > a_data_size) {
+        MSG_ERR("LIBTBD ERROR: #3 Too small data buffer given!");
+        return tbd_err_argument;
+    }
+
+    /* Check against illegal pointers */
+    if (!is_valid_pointer(a_record_data)) {
+        MSG_ERR("LIBTBD ERROR: Cannot access data!");
+        return tbd_err_data;
+    }
+
+    /* Check that the indicated data size makes sense */
+    if (a_record_size % sizeof(uint32_t)) {
+        MSG_ERR("LIBTBD ERROR: Size in record should be multiple of 4 bytes!");
+        return tbd_err_data;
+    }
+
+    /* Where our record should go */
+    record_ptr = (tbd_record_header_t *)((char *)(a_data_ptr) + header_ptr->size);
+
+    /* Create record header and store the record itself */
+    record_ptr->size = sizeof(tbd_record_header_t) + a_record_size;
+    record_ptr->format_id   = a_record_format;
+    record_ptr->packing_key = 0;
+    record_ptr->class_id    = a_record_class;
+    record_ptr++;
+    memcpy(record_ptr, a_record_data, a_record_size);
+
+    /* Update the header */
+    header_ptr->size = new_size;
+    header_ptr->checksum = 0;
+    header_ptr->checksum = get_checksum(header_ptr, new_size);
+
+    *a_new_size = new_size;
+
+    return tbd_err_none;
+}
+
+/*
+ * The indicated record is removed from the Tagged Binary Data, after
+ * which the checksum and size are updated accordingly. If there are
+ * multiple records that match the class and format, only the first
+ * instance is removed. If no record is found, nothing will be done.
+ * Note that the resulting Tagged Binary Data container will
+ * be smaller than the original, but it does not harm to store the
+ * resulting container in its original length, either.
+ * param[in]    a_data_ptr        Pointer to modifiable container buffer
+ * param[in]    a_record_class    Class the record should have
+ * param[in]    a_record_format   Format the record should have
+ * param[out]   a_new_size        Updated container size
+ * return                         Return code indicating possible errors
+ */
+tbd_error_t tbd_remove_record(void *a_data_ptr
+    , tbd_class_t a_record_class, tbd_format_t a_record_format
+    , size_t *a_new_size)
+{
+    tbd_header_t *header_ptr;
+    uint8_t *byte_ptr, *eof_ptr;
+    size_t new_size;
+
+    /* Check the the content is ok */
+    int r;
+    if ((r = validate_anysize(a_data_ptr))) {
+        return r;
+    }
+
+    /* Container should begin with a header */
+    header_ptr = a_data_ptr;
+
+    /* First record is just after header */
+    byte_ptr = (uint8_t *)(header_ptr + 1);
+    eof_ptr = (uint8_t *)(a_data_ptr) + header_ptr->size;
+
+    /* Loop until there are no more records to go */
+    while (byte_ptr < eof_ptr) {
+        /* At least one more record is expected */
+        tbd_record_header_t *record_ptr = (tbd_record_header_t *)(byte_ptr);
+
+        uint16_t record_class = record_ptr->class_id;
+        uint8_t  record_format = record_ptr->format_id;
+        uint32_t record_size = record_ptr->size;
+
+        if (((a_record_class == tbd_class_any) || (a_record_class == record_class))
+            && ((a_record_format == tbd_format_any) || (a_record_format == record_format))) {
+
+            /* Match found, remove the record */
+            memcpy(byte_ptr, byte_ptr + record_size, eof_ptr - (byte_ptr + record_size));
+
+            /* Update the header */
+            new_size = header_ptr->size - record_size;
+            header_ptr->size = new_size;
+            header_ptr->checksum = 0;
+            header_ptr->checksum = get_checksum(header_ptr, new_size);
+
+            *a_new_size = new_size;
+
+            return tbd_err_none;
+
+        }
+
+        /* Match not found yet, continue the while loop... */
+        byte_ptr += record_size;
+    }
+
+    MSG_LOG("libtbd: Record not found!");
+    *a_new_size = header_ptr->size;
+    return tbd_err_none;
+}
+
+/*
+ * Validates the Tagged Binary data container and generates a human
+ * readable detailed report on the content, including information about
+ * the records contained.
+ * param[in]    a_data_ptr        Pointer to container buffer
+ * param[in]    a_data_size       Size of the container buffer
+ * param[in]    a_outfile         Pointer to open file (may be stdout)
+ * return                         Return code indicating possible errors
+ */
+tbd_error_t tbd_infoprint(void *a_data_ptr, size_t a_data_size
+    , FILE *a_outfile)
+{
+    tbd_header_t *header_ptr;
+    uint8_t *byte_ptr, *eof_ptr, record_format, record_packing;
+    int num_of_records = 0, total_data = 0;
+    uint16_t record_class;
+    uint32_t record_size;
+
+    /* Check the the content is ok */
+    int r;
+    if ((r = validate(a_data_ptr, a_data_size))) {
+        return r;
+    }
+
+    /* Container should begin with a header */
+    header_ptr = a_data_ptr;
+
+    fprintf(a_outfile, "Data tag:      0x%08x (\'%c\' \'%c\' \'%c\' \'%c\')\n", header_ptr->tag, ((char *)(&header_ptr->tag))[0], ((char *)(&header_ptr->tag))[1], ((char *)(&header_ptr->tag))[2], ((char *)(&header_ptr->tag))[3]);
+    fprintf(a_outfile, "Data size:     %d (0x%x), buffer size %d (0x%x)\n", header_ptr->size, header_ptr->size, a_data_size, a_data_size);
+    fprintf(a_outfile, "Data version:  0x%08x\n", header_ptr->version);
+    fprintf(a_outfile, "Data revision: 0x%08x\n", header_ptr->revision);
+    fprintf(a_outfile, "Data config:   0x%08x\n", header_ptr->config_bits);
+    fprintf(a_outfile, "Data checksum: 0x%08x\n", header_ptr->checksum);
+
+    fprintf(a_outfile, "\n");
+
+    /* First record is just after header */
+    byte_ptr = (uint8_t *)(header_ptr + 1);
+    eof_ptr = (uint8_t *)(a_data_ptr) + header_ptr->size;
+
+    /* Loop until there are no more records to go */
+    while (byte_ptr < eof_ptr) {
+        /* At least one more record is expected */
+        tbd_record_header_t *record_ptr = (tbd_record_header_t *)(byte_ptr);
+        num_of_records++;
+
+        record_class = record_ptr->class_id;
+        record_format = record_ptr->format_id;
+        record_packing = record_ptr->packing_key;
+        record_size = record_ptr->size;
+        total_data += record_size - sizeof(tbd_record_header_t);
+
+        fprintf(a_outfile, "Record size:     %d (0x%x)\n", record_size, record_size);
+        fprintf(a_outfile, "Size w/o header: %d (0x%x)\n", record_size - sizeof(tbd_record_header_t), record_size - sizeof(tbd_record_header_t));
+        fprintf(a_outfile, "Record class:    %d", record_class);
+        switch (record_class) {
+        case tbd_class_any:
+            fprintf(a_outfile, " \"tbd_class_any\"\n");
+            break;
+        case tbd_class_aiq:
+            fprintf(a_outfile, " \"tbd_class_aiq\"\n");
+            break;
+        case tbd_class_drv:
+            fprintf(a_outfile, " \"tbd_class_drv\"\n");
+            break;
+        case tbd_class_hal:
+            fprintf(a_outfile, " \"tbd_class_hal\"\n");
+            break;
+        default:
+            fprintf(a_outfile, " (unknown class)\n");
+            break;
+        }
+        fprintf(a_outfile, "Record format:   %d", record_format);
+        switch (record_format) {
+        case tbd_format_any:
+            fprintf(a_outfile, " \"tbd_format_any\"\n");
+            break;
+        case tbd_format_custom:
+            fprintf(a_outfile, " \"tbd_format_custom\"\n");
+            break;
+        case tbd_format_container:
+            fprintf(a_outfile, " \"tbd_format_container\"\n");
+            break;
+        default:
+            fprintf(a_outfile, " (unknown format)\n");
+            break;
+        }
+        fprintf(a_outfile, "Packing:         %d", record_packing);
+        if (record_packing == 0) {
+            fprintf(a_outfile, " (no packing)\n");
+        } else {
+            fprintf(a_outfile, "\n");
+        }
+
+        fprintf(a_outfile, "\n");
+
+        /* Continue the while loop... */
+        byte_ptr += record_size;
+    }
+
+    fprintf(a_outfile, "Number of records found: %d\n", num_of_records);
+    fprintf(a_outfile, "Total data in records: %d bytes (without headers)\n", total_data);
+    fprintf(a_outfile, "\n");
+    return tbd_err_none;
+}
+
diff --git a/xcore/libtbd.h b/xcore/libtbd.h
new file mode 100644
index 0000000..9df7799
--- /dev/null
+++ b/xcore/libtbd.h
@@ -0,0 +1,250 @@
+/*
+** Copyright 2012-2013 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.
+*/
+
+/*
+ * \file libtbd.h
+ * \brief Tagged Binary Data handling 
+ */
+
+#ifndef __LIBTBD_H__
+#define __LIBTBD_H__
+
+#include <stddef.h>  /* defines size_t */
+#include <stdint.h>  /* defines integer types with specified widths */
+#include <stdio.h>   /* defines FILE */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!
+ *  Revision of TBD System, format 0xYYMMDDVV, where:
+ * - YY: year,
+ * - MM: month,
+ * - DD: day,
+ * - VV: version ('01','02' etc.)
+ */
+#define IA_TBD_VERSION 0x12032201
+
+/*!
+ *  Revision of TBD data set, format 0xYYMMDDVV, where:
+ * - YY: year,
+ * - MM: month,
+ * - DD: day,
+ * - VV: version ('01','02' etc.)
+ */
+#define IA_TBD_REVISION 0x13091001
+
+/*!
+* \brief Error codes for libtbd.
+*/
+typedef enum
+{
+    tbd_err_none     =       0 ,  /*!< No errors */
+    tbd_err_general  = (1 << 1),  /*!< General error */
+    tbd_err_nomemory = (1 << 2),  /*!< Out of memory */
+    tbd_err_data     = (1 << 3),  /*!< Corrupted data */
+    tbd_err_internal = (1 << 4),  /*!< Error in code */
+    tbd_err_argument = (1 << 5)   /*!< Invalid argument for a function */
+} tbd_error_t;
+
+/*!
+ * \brief Header structure for TBD container, followed by actual records.
+ */
+typedef struct
+{
+    uint32_t tag;          /*!< Tag identifier, also checks endianness */
+    uint32_t size;         /*!< Container size including this header */
+    uint32_t version;      /*!< Version of TBD system, format 0xYYMMDDVV */
+    uint32_t revision;     /*!< Revision of TBD data set, format 0xYYMMDDVV */
+    uint32_t config_bits;  /*!< Configuration flag bits set */
+    uint32_t checksum;     /*!< Global checksum, header included */
+} tbd_header_t;
+
+/*!
+ * \brief Tag identifiers used in TBD container header.
+ */
+#define CHTOU32(a,b,c,d) ((uint32_t)(a)|((uint32_t)(b)<<8)|((uint32_t)(c)<<16)|((uint32_t)(d)<<24))
+typedef enum
+{
+    tbd_tag_cpff = CHTOU32('C','P','F','F'),  /*!< CPF File */
+    tbd_tag_aiqb = CHTOU32('A','I','Q','B'),  /*!< AIQ configuration */
+    tbd_tag_aiqd = CHTOU32('A','I','Q','D'),  /*!< AIQ data */
+    tbd_tag_halb = CHTOU32('H','A','L','B'),  /*!< CameraHAL configuration */
+    tbd_tag_drvb = CHTOU32('D','R','V','B')   /*!< Sensor driver configuration */
+} tbd_tag_t;
+
+/*!
+ * \brief Record structure. Data is located right after this header.
+ */
+typedef struct
+{
+    uint32_t size;        /*!< Size of record including header */
+    uint8_t format_id;    /*!< tbd_format_t enumeration values used */
+    uint8_t packing_key;  /*!< Packing method; 0 = no packing */
+    uint16_t class_id;    /*!< tbd_class_t enumeration values used */
+} tbd_record_header_t;
+
+/*!
+ * \brief Format ID enumeration describes the data format of the record.
+ */
+typedef enum
+{
+    tbd_format_any = 0,   /*!< Unspecified format */
+    tbd_format_custom,    /*!< User specified format */
+    tbd_format_container  /*!< Record is actually another TBD container */
+} tbd_format_t;
+
+/*!
+ * \brief Class ID enumeration describes the data class of the record.
+ */
+typedef enum
+{
+    tbd_class_any = 0,  /*!< Unspecified record class */
+    tbd_class_aiq,      /*!< Used for AIC and 3A records */
+    tbd_class_drv,      /*!< Used for driver records */
+    tbd_class_hal       /*!< Used for HAL records */
+} tbd_class_t;
+
+/*!
+ * \brief Creates a new Tagged Binary Data container.
+ * Creates a new, empty Tagged Binary Data container with the tag
+ * that was given. Also updates the checksum and size accordingly.
+ * Note that the buffer size must be large enough for the header
+ * to fit in, the exact amount being 24 bytes (for tbd_header_t).
+ * @param[in]    a_data_ptr        Pointer to modifiable container buffer
+ * @param[in]    a_data_size       Size of the container buffer
+ * @param[in]    a_tag             Tag the container shall have
+ * @param[out]   a_new_size        Updated container size
+ * @return                         Return code indicating possible errors
+ */
+tbd_error_t tbd_create(void *a_data_ptr,
+    size_t a_data_size,
+    tbd_tag_t a_tag,
+    size_t *a_new_size);
+
+/*!
+ * \brief Checks if Tagged Binary Data is valid. All tags are accepted.
+ * Performs number of checks to given Tagged Binary Data container,
+ * including the verification of the checksum. The function does not
+ * care about the tag type of the container.
+ * @param[in]    a_data_ptr        Pointer to container buffer
+ * @param[in]    a_data_size       Size of the container buffer
+ * @return                         Return code indicating possible errors
+ */
+tbd_error_t tbd_validate_anytag(void *a_data_ptr,
+    size_t a_data_size);
+
+/*!
+ * \brief Checks if Tagged Binary Data is valid, and tagged properly.
+ * Performs number of checks to given Tagged Binary Data container,
+ * including the verification of the checksum. Also, the data must have
+ * been tagged properly. The tag is further used to check endianness,
+ * and if it seems wrong, a specific debug message is printed out.
+ * @param[in]    a_data_ptr        Pointer to container buffer
+ * @param[in]    a_data_size       Size of the container buffer
+ * @param[in]    a_tag             Tag the data must have
+ * @return                         Return code indicating possible errors
+ */
+tbd_error_t tbd_validate(void *a_data_ptr,
+    size_t a_data_size,
+    tbd_tag_t a_tag);
+
+/*!
+ * \brief Finds a record of given kind from within the container.
+ * Checks if a given kind of record exists in the Tagged Binary Data,
+ * and if yes, tells the location of such record as well as its size.
+ * If there are multiple records that match the query, the indicated
+ * record is the first one.
+ * @param[in]    a_data_ptr        Pointer to container buffer
+ * @param[in]    a_record_class    Class the record must have
+ * @param[in]    a_record_format   Format the record must have
+ * @param[out]   a_record_data     Record data (or NULL if not found)
+ * @param[out]   a_record_size     Record size (or 0 if not found)
+ * @return                         Return code indicating possible errors
+ */
+tbd_error_t tbd_get_record(void *a_data_ptr,
+    tbd_class_t a_record_class,
+    tbd_format_t a_record_format,
+    void **a_record_data,
+    size_t *a_record_size);
+
+/*!
+ * \brief Updates the Tagged Binary Data with the given record inserted.
+ * The given record is inserted into the Tagged Binary Data container
+ * that must exist already. New records are always added to the end,
+ * regardless if a record with the same class and format field already
+ * exists in the data. Also updates the checksum and size accordingly.
+ * Note that the buffer size must be large enough for the inserted
+ * record to fit in, the exact amount being the size of original
+ * Tagged Binary Data container plus the size of record data to be
+ * inserted plus 8 bytes (for tbd_record_header_t).
+ * @param[in]    a_data_ptr        Pointer to modifiable container buffer
+ * @param[in]    a_data_size       Size of buffer (surplus included)
+ * @param[in]    a_record_class    Class the record shall have
+ * @param[in]    a_record_format   Format the record shall have
+ * @param[in]    a_record_data     Record data
+ * @param[in]    a_record_size     Record size
+ * @param[out]   a_new_size        Updated container size
+ * @return                         Return code indicating possible errors
+ */
+tbd_error_t tbd_insert_record(void *a_data_ptr,
+    size_t a_data_size,
+    tbd_class_t a_record_class,
+    tbd_format_t a_record_format,
+    void *a_record_data,
+    size_t a_record_size,
+    size_t *a_new_size);
+
+/*!
+ * \brief Updates the Tagged Binary Data with the given record removed.
+ * The indicated record is removed from the Tagged Binary Data, after
+ * which the checksum and size are updated accordingly. If there are
+ * multiple records that match the class and format, only the first
+ * instance is removed. If no record is found, nothing will be done.
+ * Note that the resulting Tagged Binary Data container will
+ * be smaller than the original, but it does not harm to store the
+ * resulting container in its original length, either.
+ * @param[in]    a_data_ptr        Pointer to modifiable container buffer
+ * @param[in]    a_record_class    Class the record should have
+ * @param[in]    a_record_format   Format the record should have
+ * @param[out]   a_new_size        Updated container size
+ * @return                         Return code indicating possible errors
+ */
+tbd_error_t tbd_remove_record(void *a_data_ptr,
+    tbd_class_t a_record_class,
+    tbd_format_t a_record_format,
+    size_t *a_new_size);
+
+/*!
+ * \brief Writes all possible information about the Tagged Binary Data.
+ * Validates the Tagged Binary data container and generates a human
+ * readable detailed report on the content, including information about
+ * the records contained.
+ * @param[in]    a_data_ptr        Pointer to container buffer
+ * @param[in]    a_data_size       Size of the container buffer
+ * @param[in]    a_outfile         Pointer to open file (may be stdout)
+ * @return                         Return code indicating possible errors
+ */
+tbd_error_t tbd_infoprint(void *a_data_ptr,
+    size_t a_data_size,
+    FILE *a_outfile);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __LIBTBD_H__ */
diff --git a/xcore/poll_thread.cpp b/xcore/poll_thread.cpp
new file mode 100644
index 0000000..b1c6538
--- /dev/null
+++ b/xcore/poll_thread.cpp
@@ -0,0 +1,300 @@
+/*
+ * poll_thread.cpp - poll thread for event and buffer
+ *
+ *  Copyright (c) 2014-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: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#include "poll_thread.h"
+#include "xcam_thread.h"
+#include "x3a_statistics_queue.h"
+#include <unistd.h>
+
+namespace XCam {
+
+class PollThread;
+
+class EventPollThread
+    : public Thread
+{
+public:
+    EventPollThread (PollThread *poll)
+        : Thread ("event_poll")
+        , _poll (poll)
+    {}
+
+protected:
+    virtual bool started () {
+        XCamReturn ret = _poll->init_3a_stats_pool ();
+        if (ret != XCAM_RETURN_NO_ERROR)
+            return false;
+        return true;
+    }
+    virtual bool loop () {
+        XCamReturn ret = _poll->poll_subdev_event_loop ();
+
+        if (ret == XCAM_RETURN_NO_ERROR || ret == XCAM_RETURN_ERROR_TIMEOUT)
+            return true;
+        return false;
+    }
+
+private:
+    PollThread   *_poll;
+};
+
+class CapturePollThread
+    : public Thread
+{
+public:
+    CapturePollThread (PollThread *poll)
+        : Thread ("capture_poll")
+        , _poll (poll)
+    {}
+
+protected:
+    virtual bool loop () {
+        XCamReturn ret = _poll->poll_buffer_loop ();
+
+        if (ret == XCAM_RETURN_NO_ERROR || ret == XCAM_RETURN_ERROR_TIMEOUT)
+            return true;
+        return false;
+    }
+
+private:
+    PollThread   *_poll;
+};
+
+const int PollThread::default_subdev_event_timeout = 50; // ms
+const int PollThread::default_capture_event_timeout = 50; // ms
+
+PollThread::PollThread ()
+    : _callback (NULL)
+{
+    _event_loop = new EventPollThread(this);
+    _capture_loop = new CapturePollThread (this);
+
+    XCAM_LOG_DEBUG ("PollThread constructed");
+}
+
+PollThread::~PollThread ()
+{
+    stop();
+
+    XCAM_LOG_DEBUG ("~PollThread destructed");
+}
+
+
+bool
+PollThread::set_capture_device (SmartPtr<V4l2Device> &dev)
+{
+    XCAM_ASSERT (!_capture_dev.ptr());
+    _capture_dev = dev;
+    return true;
+}
+
+bool
+PollThread::set_event_device (SmartPtr<V4l2SubDevice> &dev)
+{
+    XCAM_ASSERT (!_event_dev.ptr());
+    _event_dev = dev;
+    return true;
+}
+
+bool
+PollThread::set_isp_controller (SmartPtr<IspController>  &isp)
+{
+    XCAM_ASSERT (!_isp_controller.ptr());
+    _isp_controller = isp;
+    return true;
+}
+
+bool
+PollThread::set_callback (PollCallback *callback)
+{
+    XCAM_ASSERT (!_callback);
+    _callback = callback;
+    return true;
+}
+
+XCamReturn PollThread::start ()
+{
+    _3a_stats_pool = new X3aStatisticsQueue;
+    if (!_event_loop->start ()) {
+        return XCAM_RETURN_ERROR_THREAD;
+    }
+    if (!_capture_loop->start ()) {
+        return XCAM_RETURN_ERROR_THREAD;
+    }
+
+    return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn PollThread::stop ()
+{
+    if (_3a_stats_pool.ptr ())
+        _3a_stats_pool->wakeup();
+
+    _event_loop->stop ();
+    _capture_loop->stop ();
+
+    // can't release now, stats buffer may still in use
+    //_3a_stats_pool.release ();
+    return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+PollThread::init_3a_stats_pool ()
+{
+    XCamReturn ret = XCAM_RETURN_NO_ERROR;
+    struct atomisp_parm parameters;
+
+    xcam_mem_clear (&parameters);
+    ret = _isp_controller->get_isp_parameter (parameters);
+    if (ret != XCAM_RETURN_NO_ERROR ) {
+        XCAM_LOG_WARNING ("get isp parameters failed");
+        return ret;
+    }
+    if (!parameters.info.width || !parameters.info.height) {
+        XCAM_LOG_WARNING ("get isp parameters width or height wrong");
+        return XCAM_RETURN_ERROR_ISP;
+    }
+    _3a_stats_pool->set_grid_info (parameters.info);
+    return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+PollThread::capture_3a_stats (SmartPtr<X3aIspStatistics> &stats)
+{
+    XCamReturn ret = XCAM_RETURN_NO_ERROR;
+    SmartPtr<X3aIspStatistics> new_stats = _3a_stats_pool->acquire_stats();
+
+    if (!new_stats.ptr()) {
+        XCAM_LOG_WARNING ("request stats buffer failed.");
+        return XCAM_RETURN_ERROR_MEM;
+    }
+
+    ret = _isp_controller->get_3a_statistics (new_stats);
+    if (ret != XCAM_RETURN_NO_ERROR) {
+        XCAM_LOG_WARNING ("get 3a stats from ISP failed");
+        return ret;
+    }
+
+    stats = new_stats;
+    return ret;
+}
+
+XCamReturn
+PollThread::handle_events (struct v4l2_event &event)
+{
+    XCamReturn ret = XCAM_RETURN_NO_ERROR;
+    switch (event.type) {
+    case V4L2_EVENT_ATOMISP_3A_STATS_READY:
+        ret = handle_3a_stats_event (event);
+        break;
+    case V4L2_EVENT_FRAME_SYNC:
+        break;
+    default:
+        ret = XCAM_RETURN_ERROR_UNKNOWN;
+        break;
+    }
+
+    return ret;
+}
+
+XCamReturn
+PollThread::handle_3a_stats_event (struct v4l2_event &event)
+{
+    XCamReturn ret = XCAM_RETURN_NO_ERROR;
+    SmartPtr<X3aIspStatistics> stats;
+
+    ret = capture_3a_stats (stats);
+    if (ret != XCAM_RETURN_NO_ERROR || !stats.ptr() || !stats->get_3a_stats()) {
+        XCAM_LOG_WARNING ("capture 3a stats failed");
+        return ret;
+    }
+    stats->set_timestamp (XCAM_TIMESPEC_2_USEC (event.timestamp));
+
+    XCAM_ASSERT (_callback);
+    return _callback->poll_3a_stats_ready (stats);
+}
+
+XCamReturn
+PollThread::poll_subdev_event_loop ()
+{
+    XCamReturn ret = XCAM_RETURN_NO_ERROR;
+    struct v4l2_event event;
+    int poll_ret = 0;
+
+    poll_ret = _event_dev->poll_event (PollThread::default_subdev_event_timeout);
+
+    if (poll_ret < 0) {
+        XCAM_LOG_WARNING ("poll event failed but continue");
+        ::usleep (50000); // 50ms
+        return XCAM_RETURN_ERROR_TIMEOUT;
+    }
+
+    /* timeout */
+    if (poll_ret == 0) {
+        XCAM_LOG_DEBUG ("poll event timeout and continue");
+        return XCAM_RETURN_ERROR_TIMEOUT;
+    }
+
+    xcam_mem_clear (&event);
+    ret = _event_dev->dequeue_event (event);
+    if (ret != XCAM_RETURN_NO_ERROR) {
+        XCAM_LOG_WARNING ("dequeue event failed on dev:%s", XCAM_STR(_event_dev->get_device_name()));
+        return XCAM_RETURN_ERROR_IOCTL;
+    }
+
+    ret = handle_events (event);
+    return ret;
+}
+
+XCamReturn
+PollThread::poll_buffer_loop ()
+{
+    XCamReturn ret = XCAM_RETURN_NO_ERROR;
+    int poll_ret = 0;
+    SmartPtr<V4l2Buffer> buf;
+
+    poll_ret = _capture_dev->poll_event (PollThread::default_capture_event_timeout);
+
+    if (poll_ret < 0) {
+        XCAM_LOG_WARNING ("poll buffer event got error but continue");
+        ::usleep (50000); // 50ms
+        return XCAM_RETURN_ERROR_TIMEOUT;
+    }
+
+    /* timeout */
+    if (poll_ret == 0) {
+        XCAM_LOG_DEBUG ("poll buffer timeout and continue");
+        return XCAM_RETURN_ERROR_TIMEOUT;
+    }
+
+    ret = _capture_dev->dequeue_buffer (buf);
+    if (ret != XCAM_RETURN_NO_ERROR) {
+        XCAM_LOG_WARNING ("capture buffer failed");
+        return ret;
+    }
+    XCAM_ASSERT (buf.ptr());
+    XCAM_ASSERT (_callback);
+
+    SmartPtr<V4l2BufferProxy> buf_proxy = new V4l2BufferProxy (buf, _capture_dev);
+
+    return _callback->poll_buffer_ready (buf_proxy);
+}
+
+};
diff --git a/xcore/poll_thread.h b/xcore/poll_thread.h
new file mode 100644
index 0000000..4fe8731
--- /dev/null
+++ b/xcore/poll_thread.h
@@ -0,0 +1,100 @@
+/*
+ * poll_thread.h - poll thread for event and buffer
+ *
+ *  Copyright (c) 2014-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: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#ifndef XCAM_POLL_THREAD_H
+#define XCAM_POLL_THREAD_H
+
+#include "xcam_common.h"
+#include "xcam_mutex.h"
+#include "x3a_event.h"
+#include "v4l2_buffer_proxy.h"
+#include "x3a_statistics_queue.h"
+#include "v4l2_device.h"
+#include "isp_controller.h"
+
+namespace XCam {
+
+class X3aIspStatistics;
+
+class PollCallback {
+public:
+    virtual ~PollCallback() {}
+    virtual XCamReturn poll_buffer_ready (SmartPtr<V4l2BufferProxy> &buf) = 0;
+    virtual XCamReturn poll_buffer_failed (int64_t timestamp, const char *msg) = 0;
+    virtual XCamReturn poll_3a_stats_ready (SmartPtr<X3aIspStatistics> &stats) = 0;
+    virtual XCamReturn poll_dvs_stats_ready() = 0;
+};
+
+class V4l2Device;
+class V4l2SubDevice;
+class X3aStatisticsQueue;
+class EventPollThread;
+class CapturePollThread;
+
+class PollThread
+{
+    friend class EventPollThread;
+    friend class CapturePollThread;
+public:
+    explicit PollThread ();
+    ~PollThread ();
+
+    bool set_capture_device (SmartPtr<V4l2Device> &dev);
+    bool set_event_device (SmartPtr<V4l2SubDevice> &sub_dev);
+    bool set_isp_controller (SmartPtr<IspController>  &isp);
+    bool set_callback (PollCallback *callback);
+
+    XCamReturn start();
+    XCamReturn stop ();
+
+protected:
+    XCamReturn poll_subdev_event_loop ();
+    XCamReturn poll_buffer_loop ();
+
+    XCamReturn handle_events (struct v4l2_event &event);
+    XCamReturn handle_3a_stats_event (struct v4l2_event &event);
+
+private:
+    XCamReturn init_3a_stats_pool ();
+    XCamReturn capture_3a_stats (SmartPtr<X3aIspStatistics> &stats);
+
+
+private:
+    XCAM_DEAD_COPY (PollThread);
+
+private:
+    static const int default_subdev_event_timeout;
+    static const int default_capture_event_timeout;
+
+    SmartPtr<EventPollThread>        _event_loop;
+    SmartPtr<CapturePollThread>      _capture_loop;
+
+    SmartPtr<V4l2SubDevice>          _event_dev;
+    SmartPtr<X3aStatisticsQueue>     _3a_stats_pool;
+
+    SmartPtr<V4l2Device>             _capture_dev;
+    SmartPtr<IspController>          _isp_controller;
+
+    PollCallback                    *_callback;
+};
+
+};
+
+#endif //XCAM_POLL_THREAD_H
diff --git a/xcore/safe_list.h b/xcore/safe_list.h
new file mode 100644
index 0000000..f4222cd
--- /dev/null
+++ b/xcore/safe_list.h
@@ -0,0 +1,117 @@
+/*
+ * safe_list.h - safe list template
+ *
+ *  Copyright (c) 2014 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: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#ifndef XCAM_SAFE_LIST_H
+#define XCAM_SAFE_LIST_H
+
+#include "xcam_defs.h"
+#include "xcam_common.h"
+#include "smartptr.h"
+#include "xcam_mutex.h"
+#include <errno.h>
+#include <list>
+
+namespace XCam {
+
+template<class OBj>
+class SafeList {
+public:
+    typedef SmartPtr<OBj> ObjPtr;
+
+    SafeList () {}
+    ~SafeList () {
+    }
+
+    /*
+     * timeout, -1,  wait until wakeup
+     *         >=0,  wait for @timeout microsseconds
+    */
+    inline ObjPtr pop (int32_t timeout = -1);
+    inline bool push (ObjPtr &obj);
+    uint32_t size () {
+        SmartLock lock(_mutex);
+        return _obj_list.size();
+    }
+    bool is_empty () {
+        SmartLock lock(_mutex);
+        return _obj_list.empty();
+    }
+    void wakeup () {
+        _new_obj_cond.broadcast ();
+    }
+    inline void clear ();
+
+private:
+    std::list<ObjPtr> _obj_list;
+    Mutex             _mutex;
+    XCam::Cond        _new_obj_cond;
+};
+
+
+template<class OBj>
+typename SafeList<OBj>::ObjPtr
+SafeList<OBj>::pop (int32_t timeout)
+{
+    SmartLock lock (_mutex);
+    int code = 0;
+
+    if (_obj_list.empty()) {
+        if (timeout < 0)
+            code = _new_obj_cond.wait(_mutex);
+        else
+            code = _new_obj_cond.timedwait(_mutex, timeout);
+    }
+
+    if (_obj_list.empty()) {
+        if (code == ETIMEDOUT) {
+            XCAM_LOG_DEBUG ("safe list pop timeout");
+        } else {
+            XCAM_LOG_DEBUG ("safe list pop failed");
+        }
+        return NULL;
+    }
+
+    SafeList<OBj>::ObjPtr obj = *_obj_list.begin ();
+    _obj_list.erase (_obj_list.begin ());
+    return obj;
+}
+
+template<class OBj>
+bool
+SafeList<OBj>::push (SafeList<OBj>::ObjPtr &obj)
+{
+    SmartLock lock (_mutex);
+    _obj_list.push_back (obj);
+    _new_obj_cond.signal ();
+    return true;
+}
+
+template<class OBj>
+void SafeList<OBj>::clear ()
+{
+    SmartLock lock (_mutex);
+    typename std::list<typename SafeList<OBj>::ObjPtr>::iterator i_obj = _obj_list.begin ();
+    while (i_obj != _obj_list.end ()) {
+        _obj_list.erase (i_obj++);
+    }
+}
+
+};
+#endif //XCAM_SAFE_LIST_H
diff --git a/xcore/sensor_descriptor.cpp b/xcore/sensor_descriptor.cpp
new file mode 100644
index 0000000..a749a83
--- /dev/null
+++ b/xcore/sensor_descriptor.cpp
@@ -0,0 +1,99 @@
+/*
+ * sensor_descriptor.h - sensor descriptor
+ *
+ *  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: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#include "sensor_descriptor.h"
+#include <math.h>
+
+namespace XCam {
+
+SensorDescriptor::SensorDescriptor ()
+{
+    xcam_mem_clear (&_sensor_data);
+}
+
+SensorDescriptor::~SensorDescriptor ()
+{
+}
+
+bool
+SensorDescriptor::is_ready ()
+{
+    return (_sensor_data.line_length_pck > 0);
+}
+
+void
+SensorDescriptor::set_sensor_data (struct atomisp_sensor_mode_data &data)
+{
+    _sensor_data = data;
+}
+
+bool
+SensorDescriptor::exposure_time_to_integration (
+    int32_t exposure_time, uint32_t &coarse_time, uint32_t &fine_time)
+{
+    if (exposure_time < 0 || !is_ready ())
+        return false;
+
+    uint32_t pixel_periods =  ((uint64_t)exposure_time) * _sensor_data.vt_pix_clk_freq_mhz / XCAM_SECONDS_2_TIMESTAMP (1);
+
+    coarse_time = pixel_periods / _sensor_data.line_length_pck;
+    fine_time = pixel_periods % _sensor_data.line_length_pck;
+    return true;
+}
+
+bool
+SensorDescriptor::exposure_integration_to_time (
+    uint32_t coarse_time, uint32_t fine_time, int32_t &exposure_time)
+{
+    if (!is_ready ())
+        return false;
+
+    uint64_t pixel_periods = coarse_time * _sensor_data.line_length_pck + fine_time;
+    exposure_time = pixel_periods * XCAM_SECONDS_2_TIMESTAMP(1) / _sensor_data.vt_pix_clk_freq_mhz;
+    return true;
+}
+
+bool
+SensorDescriptor::exposure_gain_to_code (
+    double analog_gain, double digital_gain,
+    int32_t &analog_code, int32_t &digital_code)
+{
+    XCAM_ASSERT (digital_gain == 1.0);
+    double db = log10 (analog_gain * digital_gain) * 20;
+    if (db > 48)
+        db = 48;
+    analog_code =  (uint32_t) (db * 160.0 / 48);
+    digital_code = 0;
+    return true;
+}
+
+bool
+SensorDescriptor::exposure_code_to_gain (
+    int32_t analog_code, int32_t digital_code,
+    double &analog_gain, double &digital_gain)
+{
+    double db = analog_code * 48.0 / 160.0;
+    analog_gain = pow (10.0, db / 20.0);
+    digital_gain = 1.0;
+
+    return true;
+}
+
+};
diff --git a/xcore/sensor_descriptor.h b/xcore/sensor_descriptor.h
new file mode 100644
index 0000000..3443539
--- /dev/null
+++ b/xcore/sensor_descriptor.h
@@ -0,0 +1,68 @@
+/*
+ * sensor_descriptor.h - sensor descriptor
+ *
+ *  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: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#ifndef XCAM_SENSOR_DESCRIPTOR_H
+#define XCAM_SENSOR_DESCRIPTOR_H
+
+#include "xcam_common.h"
+#include "xcam_defs.h"
+#include "xcam_utils.h"
+#include <linux/atomisp.h>
+
+namespace XCam {
+
+class SensorDescriptor {
+public:
+    explicit SensorDescriptor ();
+    virtual ~SensorDescriptor ();
+
+    void set_sensor_data (struct atomisp_sensor_mode_data &data);
+    virtual bool is_ready ();
+
+    // Input: exposure_time
+    // Output: coarse_time, fine_time
+    virtual bool exposure_time_to_integration (
+        int32_t exposure_time, uint32_t &coarse_time, uint32_t &fine_time);
+    // Input: coarse_time, fine_time
+    // Output: exposure_time
+    virtual bool exposure_integration_to_time (
+        uint32_t coarse_time, uint32_t fine_time, int32_t &exposure_time);
+
+    // Input : analog_gain, digital_gain
+    // Output: analog_code, digital_code
+    virtual bool exposure_gain_to_code (
+        double analog_gain, double digital_gain,
+        int32_t &analog_code, int32_t &digital_code);
+
+    // Input : analog_code, digital_code
+    // Output : analog_gain, digital_gain
+    virtual bool exposure_code_to_gain (
+        int32_t analog_code, int32_t digital_code,
+        double &analog_gain, double &digital_gain);
+
+private:
+    XCAM_DEAD_COPY (SensorDescriptor);
+
+private:
+    struct atomisp_sensor_mode_data _sensor_data;
+};
+
+};
+#endif //XCAM_SENSOR_DESCRIPTOR_H
diff --git a/xcore/smartptr.h b/xcore/smartptr.h
new file mode 100644
index 0000000..66f22d3
--- /dev/null
+++ b/xcore/smartptr.h
@@ -0,0 +1,137 @@
+/*
+ * xcam_SmartPtr.h - start pointer
+ *
+ *  Copyright (c) 2014 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: Wind Yuan <feng.yuan@intel.com>
+ */
+#ifndef XCAM_SMARTPTR_H
+#define XCAM_SMARTPTR_H
+
+#include <stdint.h>
+#include <atomic>
+#include "xcam_defs.h"
+
+namespace XCam {
+
+class RefCount {
+public:
+    RefCount (): _ref_count(1) {}
+    void ref() {
+        ++_ref_count;
+    }
+    uint32_t unref() {
+        return --_ref_count;
+    }
+private:
+    mutable std::atomic<uint32_t> _ref_count;
+};
+
+
+template <typename Obj>
+class SmartPtr {
+private:
+    template<typename ObjDerive> friend class SmartPtr;
+public:
+    SmartPtr (Obj *obj = NULL) : _ptr (obj), _ref(NULL) {
+        if (_ptr)
+            _ref = new RefCount();
+    }
+    template <typename ObjDerive>
+    SmartPtr (ObjDerive *obj) : _ptr (obj), _ref(NULL) {
+        if (_ptr)
+            _ref = new RefCount();
+    }
+
+    // copy from pointer
+    SmartPtr (const SmartPtr<Obj> &obj)
+        : _ptr(obj._ptr), _ref(obj._ref)  {
+        if (_ptr)
+            _ref->ref();
+    }
+    template <typename ObjDerive>
+    SmartPtr (const SmartPtr<ObjDerive> &obj)
+        : _ptr(obj._ptr), _ref(obj._ref)  {
+        if (_ptr)
+            _ref->ref();
+    }
+    ~SmartPtr () {
+        release();
+    }
+
+    /* operator = */
+    SmartPtr<Obj> & operator = (Obj *obj) {
+        release ();
+        new_pointer (obj, NULL);
+        return *this;
+    }
+    template <typename ObjDerive>
+    SmartPtr<Obj> & operator = (ObjDerive *obj) {
+        release ();
+        new_pointer (obj, NULL);
+        return *this;
+    }
+    SmartPtr<Obj> & operator = (const SmartPtr<Obj> &obj) {
+        release ();
+        new_pointer (obj._ptr, obj._ref);
+        return *this;
+    }
+    template <typename ObjDerive>
+    SmartPtr<Obj> & operator = (const SmartPtr<ObjDerive> &obj) {
+        release ();
+        new_pointer (obj._ptr, obj._ref);
+    }
+
+    Obj *operator -> () const {
+        return _ptr;
+    }
+
+    Obj *ptr() const {
+        return _ptr;
+    }
+
+    void release() {
+        if (!_ptr)
+            return;
+        XCAM_ASSERT (_ref);
+        if (!_ref->unref()) {
+            delete _ref;
+            delete _ptr;
+        }
+        _ptr = NULL;
+        _ref = NULL;
+    }
+private:
+    void new_pointer (Obj *obj, RefCount *ref) {
+        if (!obj) {
+            _ptr = NULL;
+            _ref = NULL;
+        }
+        _ptr = obj;
+        if (ref) {
+            _ref = ref;
+            _ref->ref();
+        } else
+            _ref = new RefCount();
+    }
+
+private:
+
+    Obj      *_ptr;
+    RefCount *_ref;
+};
+
+}; // end namespace
+#endif //XCAM_SMARTPTR_H
\ No newline at end of file
diff --git a/xcore/v4l2_buffer_proxy.cpp b/xcore/v4l2_buffer_proxy.cpp
new file mode 100644
index 0000000..64e7fb5
--- /dev/null
+++ b/xcore/v4l2_buffer_proxy.cpp
@@ -0,0 +1,115 @@
+/*
+ * v4l2_buffer_proxy.cpp - v4l2 buffer proxy
+ *
+ *  Copyright (c) 2014-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: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#include "v4l2_buffer_proxy.h"
+#include "v4l2_device.h"
+
+namespace XCam {
+V4l2Buffer::V4l2Buffer (const struct v4l2_buffer &buf, const struct v4l2_format &format)
+{
+    _buf = buf;
+    _format = format;
+}
+
+V4l2Buffer::~V4l2Buffer ()
+{
+}
+
+V4l2BufferProxy::V4l2BufferProxy (SmartPtr<V4l2Buffer> &buf, SmartPtr<V4l2Device> &device)
+    : _buf (buf)
+    , _device (device)
+{
+    VideoBufferInfo info;
+    struct timeval ts = buf->get_buf().timestamp;
+
+    xcam_mem_clear (&info);
+    v4l2_format_to_video_info (buf->get_format(), info);
+    set_video_info (info);
+    set_timestamp (XCAM_TIMEVAL_2_USEC (ts));
+}
+
+V4l2BufferProxy::~V4l2BufferProxy ()
+{
+    XCAM_ASSERT (_buf.ptr());
+    if (_device.ptr())
+        _device->queue_buffer (_buf);
+    XCAM_LOG_DEBUG ("v4l2 buffer released");
+}
+
+void
+V4l2BufferProxy::v4l2_format_to_video_info (
+    const struct v4l2_format &format, VideoBufferInfo &info)
+{
+    xcam_mem_clear (&info);
+
+    info.format = format.fmt.pix.pixelformat;
+    info.width = format.fmt.pix.width;
+    info.height = format.fmt.pix.height;
+    info.size = format.fmt.pix.sizeimage;
+    switch (format.fmt.pix.pixelformat) {
+    case V4L2_PIX_FMT_NV12:  // 420
+    case V4L2_PIX_FMT_NV21:
+        info.components = 2;
+        info.strides [0] = format.fmt.pix.bytesperline * 2 / 3;
+        info.strides [1] = format.fmt.pix.bytesperline;
+        info.offsets[0] = 0;
+        info.offsets[1] = info.strides [0] * format.fmt.pix.height;
+        break;
+    case V4L2_PIX_FMT_YUV422P: // 422
+        info.components = 3;
+        info.strides [0] = format.fmt.pix.bytesperline / 2;
+        info.strides [1] = info.strides [0] / 2 ;
+        info.strides [2] = info.strides [0] / 2 ;
+        info.offsets[0] = 0;
+        info.offsets[1] = info.strides [0] * format.fmt.pix.height;
+        info.offsets[2] = info.offsets[1] + info.strides [1] * format.fmt.pix.height;
+        break;
+    default:
+        XCAM_LOG_WARNING (
+            "unknown v4l2 format(%s) to video info",
+            xcam_fourcc_to_string (format.fmt.pix.pixelformat));
+        break;
+    }
+
+}
+
+const struct v4l2_buffer &
+V4l2BufferProxy::get_v4l2_buf () const
+{
+    XCAM_ASSERT (_buf.ptr());
+    return _buf->get_buf ();
+}
+
+uint8_t *
+V4l2BufferProxy::map ()
+{
+    const struct v4l2_buffer & v4l2_buf = get_v4l2_buf ();
+    if (v4l2_buf.memory == V4L2_MEMORY_DMABUF)
+        return NULL;
+    return (uint8_t *)(v4l2_buf.m.userptr);
+}
+
+bool
+V4l2BufferProxy::unmap ()
+{
+    return true;
+}
+
+};
diff --git a/xcore/v4l2_buffer_proxy.h b/xcore/v4l2_buffer_proxy.h
new file mode 100644
index 0000000..af09936
--- /dev/null
+++ b/xcore/v4l2_buffer_proxy.h
@@ -0,0 +1,121 @@
+/*
+ * v4l2_buffer_proxy.h - v4l2 buffer proxy
+ *
+ *  Copyright (c) 2014-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: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#ifndef XCAM_V4L2_BUFFER_PROXY_H
+#define XCAM_V4L2_BUFFER_PROXY_H
+
+#include "video_buffer.h"
+#include "smartptr.h"
+#include <linux/videodev2.h>
+
+namespace XCam {
+
+class V4l2Device;
+
+class V4l2Buffer {
+public:
+    explicit V4l2Buffer (const struct v4l2_buffer &buf, const struct v4l2_format &format);
+    virtual ~V4l2Buffer ();
+
+    const struct v4l2_buffer & get_buf () const {
+        return _buf;
+    }
+
+    void set_timestamp (const struct timeval &time) {
+        _buf.timestamp = time;
+    }
+
+    void set_timecode (const struct v4l2_timecode &code) {
+        _buf.timecode = code;
+    }
+
+    void set_sequence (const uint32_t sequence) {
+        _buf.sequence = sequence;
+    }
+
+    void set_length (const uint32_t value) {
+        _buf.length = value;
+    }
+
+    void reset () {
+        xcam_mem_clear (&_buf.timestamp);
+        xcam_mem_clear (&_buf.timecode);
+        _buf.sequence = 0;
+        //_buf.length = 0;
+    }
+
+    const struct v4l2_format & get_format () const {
+        return _format;
+    }
+
+private:
+    XCAM_DEAD_COPY (V4l2Buffer);
+
+private:
+    struct v4l2_buffer  _buf;
+    struct v4l2_format  _format;
+};
+
+class V4l2BufferProxy
+    : public VideoBuffer
+{
+public:
+    explicit V4l2BufferProxy (SmartPtr<V4l2Buffer> &buf, SmartPtr<V4l2Device> &device);
+
+    ~V4l2BufferProxy ();
+
+    int get_v4l2_buf_index () {
+        return get_v4l2_buf().index;
+    }
+
+    int get_v4l2_mem_type () {
+        return get_v4l2_buf().memory;
+    }
+
+    int get_v4l2_buf_length () {
+        return get_v4l2_buf().length;
+    }
+
+    int get_v4l2_dma_fd () {
+        return get_v4l2_buf().m.fd;
+    }
+
+    uintptr_t get_v4l2_userptr () {
+        return get_v4l2_buf().m.userptr;
+    }
+
+    virtual uint8_t *map ();
+    virtual bool unmap ();
+
+private:
+    const struct v4l2_buffer & get_v4l2_buf () const;
+
+    void v4l2_format_to_video_info (
+        const struct v4l2_format &format, VideoBufferInfo &info);
+
+    XCAM_DEAD_COPY (V4l2BufferProxy);
+
+private:
+    SmartPtr<V4l2Buffer>  _buf;
+    SmartPtr<V4l2Device>  _device;
+};
+};
+
+#endif //XCAM_V4L2_BUFFER_PROXY_H
diff --git a/xcore/v4l2_device.cpp b/xcore/v4l2_device.cpp
new file mode 100644
index 0000000..ea4d225
--- /dev/null
+++ b/xcore/v4l2_device.cpp
@@ -0,0 +1,691 @@
+/*
+ * v4l2_device.cpp - v4l2 device
+ *
+ *  Copyright (c) 2014-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: Wind Yuan <feng.yuan@intel.com>
+ * Author: John Ye <john.ye@intel.com>
+ */
+
+#include "v4l2_device.h"
+#include <sys/ioctl.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <poll.h>
+#include <sys/mman.h>
+
+#include "v4l2_buffer_proxy.h"
+
+namespace XCam {
+
+#define XCAM_V4L2_DEFAULT_BUFFER_COUNT  6
+
+V4l2Device::V4l2Device (const char *name)
+    : _name (NULL)
+    , _fd (-1)
+    , _sensor_id (0)
+    , _capture_mode (0)
+    , _capture_buf_type (V4L2_BUF_TYPE_VIDEO_CAPTURE)
+    , _memory_type (V4L2_MEMORY_MMAP)
+    , _fps_n (0)
+    , _fps_d (0)
+    , _active (false)
+    , _buf_count (XCAM_V4L2_DEFAULT_BUFFER_COUNT)
+{
+    if (name)
+        _name = strdup (name);
+    xcam_mem_clear (&_format);
+}
+
+V4l2Device::~V4l2Device ()
+{
+    close();
+    if (_name)
+        xcam_free (_name);
+}
+
+bool
+V4l2Device::set_device_name (const char *name)
+{
+    XCAM_ASSERT (name);
+
+    if (is_opened()) {
+        XCAM_LOG_WARNING ("can't set device name since device opened");
+        return false;
+    }
+    if (_name)
+        xcam_free (_name);
+    _name = strdup (name);
+    return true;
+}
+
+bool
+V4l2Device::set_sensor_id (int id)
+{
+    if (is_opened()) {
+        XCAM_LOG_WARNING ("can't set sensor id since device opened");
+        return false;
+    }
+    _sensor_id = id;
+    return true;
+}
+
+bool
+V4l2Device::set_capture_mode (uint32_t capture_mode)
+{
+    if (is_opened()) {
+        XCAM_LOG_WARNING ("can't set sensor id since device opened");
+        return false;
+    }
+    _capture_mode = capture_mode;
+    return true;
+}
+
+bool
+V4l2Device::set_framerate (uint32_t n, uint32_t d)
+{
+    if (_format.fmt.pix.pixelformat) {
+        XCAM_LOG_WARNING ("device(%s) set framerate failed since formated was already set.", XCAM_STR(_name));
+        return false;
+    }
+
+    _fps_n = n;
+    _fps_d = d;
+
+    return true;
+}
+
+void
+V4l2Device::get_framerate (uint32_t &n, uint32_t &d)
+{
+    n = _fps_n;
+    d = _fps_d;
+}
+
+bool
+V4l2Device::set_mem_type (enum v4l2_memory type) {
+    if (is_activated ()) {
+        XCAM_LOG_WARNING ("device(%s) set mem type failed", XCAM_STR (_name));
+        return false;
+    }
+    _memory_type = type;
+    return true;
+}
+
+bool
+V4l2Device::set_buffer_count (uint32_t buf_count)
+{
+    if (is_activated ()) {
+        XCAM_LOG_WARNING ("device(%s) set buffer count failed", XCAM_STR (_name));
+        return false;
+    }
+    _buf_count = buf_count;
+    return true;
+}
+
+
+XCamReturn
+V4l2Device::open ()
+{
+    struct v4l2_streamparm param;
+
+    if (is_opened()) {
+        XCAM_LOG_DEBUG ("device(%s) was already opened", XCAM_STR(_name));
+        return XCAM_RETURN_NO_ERROR;
+    }
+
+    if (!_name) {
+        XCAM_LOG_DEBUG ("v4l2 device open failed, there's no device name");
+        return XCAM_RETURN_ERROR_PARAM;
+    }
+    _fd = ::open (_name, O_RDWR);
+    if (_fd == -1) {
+        XCAM_LOG_DEBUG ("open device(%s) failed", _name);
+        return XCAM_RETURN_ERROR_IOCTL;
+    }
+
+    // set sensor id
+    if (io_control (VIDIOC_S_INPUT, &_sensor_id) < 0) {
+        XCAM_LOG_WARNING ("set sensor id(%d) failed but continue", _sensor_id);
+    }
+
+    // set capture mode
+    xcam_mem_clear (&param);
+    param.type = _capture_buf_type;
+    param.parm.capture.capturemode = _capture_mode;
+    if (io_control (VIDIOC_S_PARM, &param) < 0) {
+        XCAM_LOG_WARNING ("set capture mode(0x%08x) failed but continue", _capture_mode);
+    }
+
+    return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+V4l2Device::close ()
+{
+    if (!is_opened())
+        return XCAM_RETURN_NO_ERROR;
+    ::close (_fd);
+    _fd = -1;
+    return XCAM_RETURN_NO_ERROR;
+}
+
+int
+V4l2Device::io_control (int cmd, void *arg)
+
+{
+    if (_fd <= 0)
+        return -1;
+
+    return xcam_device_ioctl (_fd, cmd, arg);
+}
+
+int
+V4l2Device::poll_event (int timeout_msec)
+{
+    struct pollfd poll_fd;
+    int ret = 0;
+
+    XCAM_ASSERT (_fd > 0);
+
+    xcam_mem_clear (&poll_fd);
+    poll_fd.fd = _fd;
+    poll_fd.events = (POLLPRI | POLLIN | POLLERR | POLLNVAL | POLLHUP);
+
+    ret = poll (&poll_fd, 1, timeout_msec);
+    if (ret > 0 && (poll_fd.revents & (POLLERR | POLLNVAL | POLLHUP))) {
+        XCAM_LOG_DEBUG ("v4l2 subdev(%s) polled error", XCAM_STR(_name));
+        return -1;
+    }
+    return ret;
+
+}
+
+XCamReturn
+V4l2Device::set_format (struct v4l2_format &format)
+{
+    XCamReturn ret = XCAM_RETURN_NO_ERROR;
+
+    XCAM_FAIL_RETURN (ERROR, !is_activated (), XCAM_RETURN_ERROR_PARAM,
+                      "Cannot set format to v4l2 device while it is active.");
+
+    XCAM_FAIL_RETURN (ERROR, is_opened (), XCAM_RETURN_ERROR_FILE,
+                      "Cannot set format to v4l2 device while it is closed.");
+
+    ret = pre_set_format (format);
+    if (ret != XCAM_RETURN_NO_ERROR) {
+        XCAM_LOG_WARNING ("device(%s) pre_set_format failed", XCAM_STR (_name));
+        return ret;
+    }
+
+    if (io_control (VIDIOC_S_FMT, &format) < 0) {
+        if (errno == EBUSY) {
+            // TODO log device name
+            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.");
+        }
+
+        return XCAM_RETURN_ERROR_IOCTL;
+    }
+
+    while (_fps_n && _fps_d) {
+        struct v4l2_streamparm param;
+        xcam_mem_clear (&param);
+        param.type = _capture_buf_type;
+        if (io_control (VIDIOC_G_PARM, &param) < 0) {
+            XCAM_LOG_WARNING ("device(%s) set framerate failed on VIDIOC_G_PARM but continue", XCAM_STR (_name));
+            break;
+        }
+
+        if (!(param.parm.capture.capability & V4L2_CAP_TIMEPERFRAME))
+            break;
+
+        param.parm.capture.timeperframe.numerator = _fps_d;
+        param.parm.capture.timeperframe.denominator = _fps_n;
+
+        if (io_control (VIDIOC_S_PARM, &param) < 0) {
+            XCAM_LOG_WARNING ("device(%s) set framerate failed on VIDIOC_S_PARM but continue", XCAM_STR (_name));
+            break;
+        }
+        _fps_n = param.parm.capture.timeperframe.denominator;
+        _fps_d = param.parm.capture.timeperframe.numerator;
+        XCAM_LOG_INFO ("device(%s) set framerate(%d/%d)", XCAM_STR (_name), _fps_n, _fps_d);
+    }
+
+    ret = post_set_format (format);
+    if (ret != XCAM_RETURN_NO_ERROR) {
+        XCAM_LOG_WARNING ("device(%s) post_set_format failed", XCAM_STR (_name));
+        return ret;
+    }
+
+    _format = format;
+    XCAM_LOG_INFO (
+        "device(%s) set format(w:%d, h:%d, pixelformat:%s, bytesperline:%d,image_size:%d)",
+        XCAM_STR (_name),
+        format.fmt.pix.width, format.fmt.pix.height,
+        xcam_fourcc_to_string (format.fmt.pix.pixelformat),
+        format.fmt.pix.bytesperline,
+        format.fmt.pix.sizeimage);
+
+    return XCAM_RETURN_NO_ERROR;
+}
+
+/*! \brief v4l2 set format
+ *
+ * \param[in]    width            format width
+ * \param[in]    height           format height
+ * \param[in]    pixelformat      fourcc
+ * \param[in]    field            V4L2_FIELD_INTERLACED or V4L2_FIELD_NONE
+ */
+XCamReturn
+V4l2Device::set_format (
+    uint32_t width,  uint32_t height,
+    uint32_t pixelformat, enum v4l2_field field, uint32_t bytes_perline)
+{
+
+    struct v4l2_format format;
+    xcam_mem_clear (&format);
+
+    format.type = _capture_buf_type;
+    format.fmt.pix.width = width;
+    format.fmt.pix.height = height;
+    format.fmt.pix.pixelformat = pixelformat;
+    format.fmt.pix.field = field;
+
+    if (bytes_perline != 0)
+        format.fmt.pix.bytesperline = bytes_perline;
+
+    return set_format (format);
+}
+
+XCamReturn
+V4l2Device::pre_set_format (struct v4l2_format &format)
+{
+    XCAM_UNUSED (format);
+    return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+V4l2Device::post_set_format (struct v4l2_format &format)
+{
+    XCAM_UNUSED (format);
+    return XCAM_RETURN_NO_ERROR;
+}
+
+std::list<struct v4l2_fmtdesc>
+V4l2Device::enum_formats ()
+{
+    std::list<struct v4l2_fmtdesc> formats;
+    struct v4l2_fmtdesc format;
+    uint32_t i = 0;
+
+    while (1) {
+        xcam_mem_clear (&format);
+        format.index = i++;
+        format.type = _capture_buf_type;
+        if (this->io_control (VIDIOC_ENUM_FMT, &format) < 0) {
+            if (errno == EINVAL)
+                break;
+            else { // error
+                XCAM_LOG_DEBUG ("enum formats failed");
+                return formats;
+            }
+        }
+        formats.push_back (format);
+    }
+
+    return formats;
+}
+
+XCamReturn
+V4l2Device::get_format (struct v4l2_format &format)
+{
+    if (is_activated ()) {
+        format = _format;
+        return XCAM_RETURN_NO_ERROR;
+    }
+
+    if (!is_opened ())
+        return XCAM_RETURN_ERROR_IOCTL;
+
+    xcam_mem_clear (&format);
+    format.type = _capture_buf_type;
+
+    if (this->io_control (VIDIOC_G_FMT, &format) < 0) {
+        // FIXME: also log the device name?
+        XCAM_LOG_ERROR("Fail to get format via ioctl VIDVIO_G_FMT.");
+        return XCAM_RETURN_ERROR_IOCTL;
+    }
+
+    return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+V4l2Device::start ()
+{
+    XCamReturn ret = XCAM_RETURN_NO_ERROR;
+    // request buffer first
+    ret = request_buffer ();
+    XCAM_FAIL_RETURN (
+        ERROR, ret == XCAM_RETURN_NO_ERROR, ret,
+        "device(%s) start failed", XCAM_STR (_name));
+
+    //alloc buffers
+    ret = init_buffer_pool ();
+    XCAM_FAIL_RETURN (
+        ERROR, ret == XCAM_RETURN_NO_ERROR, ret,
+        "device(%s) start failed", XCAM_STR (_name));
+
+    //queue all buffers
+    for (uint32_t i = 0; i < _buf_count; ++i) {
+        SmartPtr<V4l2Buffer> &buf = _buf_pool [i];
+        XCAM_ASSERT (buf.ptr());
+        XCAM_ASSERT (buf->get_buf().index == i);
+        ret = queue_buffer (buf);
+        if (ret != XCAM_RETURN_NO_ERROR) {
+            XCAM_LOG_ERROR (
+                "device(%s) start failed on queue index:%d",
+                XCAM_STR (_name), i);
+            stop ();
+            return ret;
+        }
+    }
+
+    // stream on
+    if (io_control (VIDIOC_STREAMON, &_capture_buf_type) < 0) {
+        XCAM_LOG_ERROR (
+            "device(%s) start failed on VIDIOC_STREAMON",
+            XCAM_STR (_name));
+        stop ();
+        return XCAM_RETURN_ERROR_IOCTL;
+    }
+    _active = true;
+    XCAM_LOG_INFO ("device(%s) started successfully", XCAM_STR (_name));
+    return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+V4l2Device::stop ()
+{
+    // stream off
+    if (_active) {
+        if (io_control (VIDIOC_STREAMOFF, &_capture_buf_type) < 0) {
+            XCAM_LOG_WARNING ("device(%s) steamoff failed", XCAM_STR (_name));
+        }
+        _active = false;
+    }
+
+    fini_buffer_pool ();
+
+    XCAM_LOG_INFO ("device(%s) stopped", XCAM_STR (_name));
+    return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+V4l2Device::request_buffer ()
+{
+    struct v4l2_requestbuffers request_buf;
+
+    XCAM_ASSERT (!is_activated());
+
+    xcam_mem_clear (&request_buf);
+    request_buf.type = _capture_buf_type;
+    request_buf.count = _buf_count;
+    request_buf.memory = _memory_type;
+
+    if (io_control (VIDIOC_REQBUFS, &request_buf) < 0) {
+        XCAM_LOG_INFO ("device(%s) starts failed on VIDIOC_REQBUFS", XCAM_STR (_name));
+        return XCAM_RETURN_ERROR_IOCTL;
+    }
+
+    if (request_buf.count != _buf_count) {
+        XCAM_LOG_DEBUG (
+            "device(%s) request buffer count doesn't match user settings, reset buffer count to %d",
+            XCAM_STR (_name), request_buf.count);
+        _buf_count = request_buf.count;
+    }
+    return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+V4l2Device::allocate_buffer (
+    SmartPtr<V4l2Buffer> &buf,
+    const struct v4l2_format &format,
+    const uint32_t index)
+{
+    struct v4l2_buffer v4l2_buf;
+
+    xcam_mem_clear (&v4l2_buf);
+    v4l2_buf.index = index;
+    v4l2_buf.type = _capture_buf_type;
+    v4l2_buf.memory = _memory_type;
+
+    switch (_memory_type) {
+    case V4L2_MEMORY_DMABUF:
+    {
+        struct v4l2_exportbuffer expbuf;
+        xcam_mem_clear (&expbuf);
+        expbuf.type = _capture_buf_type;
+        expbuf.index = index;
+        expbuf.flags = O_CLOEXEC;
+        if (io_control (VIDIOC_EXPBUF, &expbuf) < 0) {
+            XCAM_LOG_WARNING ("device(%s) get dma buf(%d) failed", XCAM_STR (_name), index);
+            return XCAM_RETURN_ERROR_MEM;
+        }
+        v4l2_buf.m.fd = expbuf.fd;
+        v4l2_buf.length = format.fmt.pix.sizeimage;
+    }
+    break;
+    case V4L2_MEMORY_MMAP:
+    {
+        void *pointer;
+        if (io_control (VIDIOC_QUERYBUF, &v4l2_buf) < 0) {
+            XCAM_LOG_WARNING("device(%s) query MMAP buf(%d) failed", XCAM_STR(_name), index);
+            return XCAM_RETURN_ERROR_MEM;
+        }
+        pointer = mmap (0, v4l2_buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, _fd, v4l2_buf.m.offset);
+        if (pointer == MAP_FAILED) {
+            XCAM_LOG_WARNING("device(%s) mmap buf(%d) failed", XCAM_STR(_name), index);
+            return XCAM_RETURN_ERROR_MEM;
+        }
+        v4l2_buf.m.userptr = (uintptr_t) pointer;
+    }
+    break;
+    case V4L2_MEMORY_USERPTR:
+    default:
+        XCAM_ASSERT (false);
+        XCAM_LOG_WARNING (
+            "device(%s) allocated buffer mem_type(%d) doesn't support",
+            XCAM_STR (_name), _memory_type);
+        return XCAM_RETURN_ERROR_MEM;
+    }
+
+    buf = new V4l2Buffer (v4l2_buf, _format);
+
+    return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+V4l2Device::init_buffer_pool ()
+{
+    XCamReturn ret = XCAM_RETURN_NO_ERROR;
+    uint32_t i = 0;
+
+    _buf_pool.clear ();
+    _buf_pool.reserve (_buf_count);
+
+    for (; i < _buf_count; i++) {
+        SmartPtr<V4l2Buffer> new_buf;
+        ret = allocate_buffer (new_buf, _format, i);
+        if (ret != XCAM_RETURN_NO_ERROR) {
+            break;
+        }
+        _buf_pool.push_back (new_buf);
+    }
+
+    if (_buf_pool.empty()) {
+        XCAM_LOG_ERROR ("No bufer allocated in device(%s)", XCAM_STR (_name));
+        return XCAM_RETURN_ERROR_MEM;
+    }
+
+    if (i != _buf_count) {
+        XCAM_LOG_WARNING (
+            "device(%s) allocate buffer count:%d failback to %d",
+            XCAM_STR (_name), _buf_count, i);
+        _buf_count = i;
+    }
+
+    return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+V4l2Device::fini_buffer_pool()
+{
+    _buf_pool.clear ();
+    return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+V4l2Device::dequeue_buffer(SmartPtr<V4l2Buffer> &buf)
+{
+    struct v4l2_buffer v4l2_buf;
+
+    if (!is_activated()) {
+        XCAM_LOG_DEBUG (
+            "device(%s) dequeue buffer failed since not activated", XCAM_STR (_name));
+        return XCAM_RETURN_ERROR_PARAM;
+    }
+
+    xcam_mem_clear (&v4l2_buf);
+    v4l2_buf.type = _capture_buf_type;
+    v4l2_buf.memory = _memory_type;
+
+    if (this->io_control (VIDIOC_DQBUF, &v4l2_buf) < 0) {
+        XCAM_LOG_ERROR ("device(%s) fail to dequeue buffer.", XCAM_STR (_name));
+        return XCAM_RETURN_ERROR_IOCTL;
+    }
+
+    XCAM_LOG_DEBUG ("device(%s) dequeue buffer index:%d", XCAM_STR (_name), v4l2_buf.index);
+
+    if (v4l2_buf.index > _buf_count) {
+        XCAM_LOG_ERROR (
+            "device(%s) dequeue wrong buffer index:%d",
+            XCAM_STR (_name), v4l2_buf.index);
+        return XCAM_RETURN_ERROR_ISP;
+    }
+    buf = _buf_pool [v4l2_buf.index];
+    buf->set_timestamp (v4l2_buf.timestamp);
+    buf->set_timecode (v4l2_buf.timecode);
+    buf->set_sequence (v4l2_buf.sequence);
+    //buf.set_length (v4l2_buf.length); // not necessary to set length
+    return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+V4l2Device::queue_buffer (SmartPtr<V4l2Buffer> &buf)
+{
+    XCAM_ASSERT (buf.ptr());
+    buf->reset ();
+
+    struct v4l2_buffer v4l2_buf = buf->get_buf ();
+    XCAM_ASSERT (v4l2_buf.index < _buf_count);
+
+    XCAM_LOG_DEBUG ("device(%s) queue buffer index:%d", XCAM_STR (_name), v4l2_buf.index);
+    if (io_control (VIDIOC_QBUF, &v4l2_buf) < 0) {
+        XCAM_LOG_ERROR("fail to enqueue buffer index:%d.", v4l2_buf.index);
+        return XCAM_RETURN_ERROR_IOCTL;
+    }
+    return XCAM_RETURN_NO_ERROR;
+}
+
+V4l2SubDevice::V4l2SubDevice (const char *name)
+    : V4l2Device (name)
+{
+}
+
+XCamReturn
+V4l2SubDevice::subscribe_event (int event)
+{
+    struct v4l2_event_subscription sub;
+    int ret = 0;
+
+    XCAM_ASSERT (is_opened());
+
+    xcam_mem_clear (&sub);
+    sub.type = event;
+
+    ret = this->io_control (VIDIOC_SUBSCRIBE_EVENT, &sub);
+    if (ret < 0) {
+        XCAM_LOG_DEBUG ("subdev(%s) subscribe event(%d) failed", XCAM_STR(_name), event);
+        return XCAM_RETURN_ERROR_IOCTL;
+    }
+    return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+V4l2SubDevice::unsubscribe_event (int event)
+{
+    struct v4l2_event_subscription sub;
+    int ret = 0;
+
+    XCAM_ASSERT (is_opened());
+
+    xcam_mem_clear (&sub);
+    sub.type = event;
+
+    ret = this->io_control (VIDIOC_UNSUBSCRIBE_EVENT, &sub);
+    if (ret < 0) {
+        XCAM_LOG_DEBUG ("subdev(%s) unsubscribe event(%d) failed", XCAM_STR(_name), event);
+        return XCAM_RETURN_ERROR_IOCTL;
+    }
+    return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+V4l2SubDevice::dequeue_event (struct v4l2_event &event)
+{
+    int ret = 0;
+    XCAM_ASSERT (is_opened());
+
+    ret = this->io_control (VIDIOC_DQEVENT, &event);
+    if (ret < 0) {
+        XCAM_LOG_DEBUG ("subdev(%s) dequeue event failed", XCAM_STR(_name));
+        return XCAM_RETURN_ERROR_IOCTL;
+    }
+
+    return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn V4l2SubDevice::start ()
+{
+    if (!is_opened())
+        return XCAM_RETURN_ERROR_PARAM;
+
+    _active = true;
+    return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn V4l2SubDevice::stop ()
+{
+    if (_active)
+        _active = false;
+
+    return XCAM_RETURN_NO_ERROR;
+}
+
+};
diff --git a/xcore/v4l2_device.h b/xcore/v4l2_device.h
new file mode 100644
index 0000000..fa09c53
--- /dev/null
+++ b/xcore/v4l2_device.h
@@ -0,0 +1,168 @@
+/*
+ * v4l2_device.h - v4l2 device
+ *
+ *  Copyright (c) 2014-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: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#ifndef XCAM_V4L2_DEVICE_H
+#define XCAM_V4L2_DEVICE_H
+
+#include "xcam_common.h"
+#include "smartptr.h"
+#include <linux/videodev2.h>
+#include <list>
+#include <vector>
+
+extern "C" {
+    struct v4l2_event;
+    struct v4l2_format;
+    struct v4l2_fmtdesc;
+    struct v4l2_frmsizeenum;
+}
+
+namespace XCam {
+
+class V4l2Buffer;
+
+class V4l2Device {
+    friend class V4l2BufferProxy;
+    typedef std::vector<SmartPtr<V4l2Buffer>> BufferPool;
+
+public:
+    V4l2Device (const char *name = NULL);
+    virtual ~V4l2Device ();
+
+    // before device open
+    bool set_device_name (const char *name);
+    bool set_sensor_id (int id);
+    bool set_capture_mode (uint32_t capture_mode);
+
+    int get_fd () const {
+        return _fd;
+    }
+    const char *get_device_name () const {
+        return _name;
+    }
+    bool is_opened () const    {
+        return (_fd != -1);
+    }
+    bool is_activated () const {
+        return _active;
+    }
+
+    // set_mem_type must before set_format
+    bool set_mem_type (enum v4l2_memory type);
+    enum v4l2_memory get_mem_type () const {
+        return _memory_type;
+    }
+    enum v4l2_buf_type get_capture_buf_type () const {
+        return _capture_buf_type;
+    }
+    void get_size (uint32_t &width, uint32_t &height) const {
+        width = _format.fmt.pix.width;
+        height = _format.fmt.pix.height;
+    }
+    uint32_t get_pixel_format () const {
+        return _format.fmt.pix.pixelformat;
+    }
+
+    bool set_buffer_count (uint32_t buf_count);
+
+    // set_framerate must before set_format
+    bool set_framerate (uint32_t n, uint32_t d);
+    void get_framerate (uint32_t &n, uint32_t &d);
+
+    XCamReturn open ();
+    XCamReturn close ();
+    // set_format
+    XCamReturn get_format (struct v4l2_format &format);
+    XCamReturn set_format (struct v4l2_format &format);
+    XCamReturn set_format (
+        uint32_t width, uint32_t height, uint32_t pixelformat,
+        enum v4l2_field field = V4L2_FIELD_NONE, uint32_t bytes_perline = 0);
+
+    std::list<struct v4l2_fmtdesc> enum_formats ();
+
+    virtual XCamReturn start ();
+    virtual XCamReturn stop ();
+
+    int poll_event (int timeout_msec);
+    XCamReturn dequeue_buffer (SmartPtr<V4l2Buffer> &buf);
+    XCamReturn queue_buffer (SmartPtr<V4l2Buffer> &buf);
+
+    // use as less as possible
+    int io_control (int cmd, void *arg);
+
+protected:
+
+    //virtual functions, handle private actions on set_format
+    virtual XCamReturn pre_set_format (struct v4l2_format &format);
+    virtual XCamReturn post_set_format (struct v4l2_format &format);
+    virtual XCamReturn allocate_buffer (
+        SmartPtr<V4l2Buffer> &buf,
+        const struct v4l2_format &format,
+        const uint32_t index);
+
+private:
+    XCamReturn request_buffer ();
+    XCamReturn init_buffer_pool ();
+    XCamReturn fini_buffer_pool ();
+
+    XCAM_DEAD_COPY (V4l2Device);
+
+protected:
+    char               *_name;
+    int                 _fd;
+    int32_t             _sensor_id;
+    uint32_t            _capture_mode;
+    enum v4l2_buf_type  _capture_buf_type;
+    enum v4l2_memory    _memory_type;
+
+    struct v4l2_format  _format;
+    uint32_t            _fps_n;
+    uint32_t            _fps_d;
+
+    bool                _active;
+
+    // buffer pool
+    BufferPool          _buf_pool;
+    uint32_t            _buf_count;
+
+    XCamReturn buffer_new();
+    XCamReturn buffer_del();
+};
+
+class V4l2SubDevice
+    : public V4l2Device
+{
+public:
+    explicit V4l2SubDevice (const char *name = NULL);
+
+    XCamReturn subscribe_event (int event);
+    XCamReturn unsubscribe_event (int event);
+    XCamReturn dequeue_event (struct v4l2_event &event);
+
+    virtual XCamReturn start ();
+    virtual XCamReturn stop ();
+
+private:
+    XCAM_DEAD_COPY (V4l2SubDevice);
+};
+
+};
+#endif // XCAM_V4L2_DEVICE_H
+
diff --git a/xcore/video_buffer.h b/xcore/video_buffer.h
new file mode 100644
index 0000000..66e9ce9
--- /dev/null
+++ b/xcore/video_buffer.h
@@ -0,0 +1,78 @@
+/*
+ * video_buffer.h - video buffer base
+ *
+ *  Copyright (c) 2014-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: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#ifndef XCAM_VIDEO_BUFFER_H
+#define XCAM_VIDEO_BUFFER_H
+
+#include "xcam_defs.h"
+#include "xcam_common.h"
+#include "xcam_utils.h"
+
+namespace XCam {
+
+#define XCAM_VIDEO_MAX_COMPONENTS 4
+
+typedef struct _VideoBufferInfo {
+    uint32_t format;
+    uint32_t width;
+    uint32_t height;
+    uint32_t size;
+    uint32_t components;
+    uint32_t strides [XCAM_VIDEO_MAX_COMPONENTS];
+    uint32_t offsets [XCAM_VIDEO_MAX_COMPONENTS];
+} VideoBufferInfo;
+
+class VideoBuffer {
+public:
+    explicit VideoBuffer (int64_t timestamp = InvalidTimestamp)
+        : _timestamp (timestamp)
+    {}
+    explicit VideoBuffer (const VideoBufferInfo &info, int64_t timestamp = InvalidTimestamp)
+        : _videoinfo (info)
+        , _timestamp (timestamp)
+    {}
+    virtual ~VideoBuffer () {}
+
+    virtual uint8_t *map () = 0;
+    virtual bool unmap () = 0;
+
+    const VideoBufferInfo & get_video_info () const {
+        return _videoinfo;
+    }
+    int64_t get_timestamp () const {
+        return _timestamp;
+    }
+
+    void set_video_info (const VideoBufferInfo &info) {
+        _videoinfo = info;
+    }
+
+    void set_timestamp (int64_t timestamp) {
+        _timestamp = timestamp;
+    }
+
+private:
+    VideoBufferInfo _videoinfo;
+    int64_t         _timestamp; // in microseconds
+};
+
+};
+
+#endif //XCAM_BUFFER_PROXY_H
diff --git a/xcore/x3a_analyzer.cpp b/xcore/x3a_analyzer.cpp
new file mode 100644
index 0000000..57b5264
--- /dev/null
+++ b/xcore/x3a_analyzer.cpp
@@ -0,0 +1,548 @@
+/*
+ * x3a_analyzer.cpp - 3a analyzer
+ *
+ *  Copyright (c) 2014-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: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#include "x3a_analyzer.h"
+#include "xcam_thread.h"
+#include "safe_list.h"
+#include "x3a_statistics_queue.h"
+
+namespace XCam {
+
+class AnalyzerThread
+    : public Thread
+{
+public:
+    AnalyzerThread (X3aAnalyzer *analyzer);
+    ~AnalyzerThread ();
+
+    void triger_stop() {
+        _3a_stats_queue.wakeup ();
+    }
+    bool push_stats (SmartPtr<X3aIspStatistics> &stats);
+
+protected:
+    virtual bool started ();
+    virtual void stopped () {
+        _3a_stats_queue.clear ();
+    }
+    virtual bool loop ();
+
+private:
+    X3aAnalyzer               *_analyzer;
+    SafeList<X3aIspStatistics> _3a_stats_queue;
+};
+
+AnalyzerThread::AnalyzerThread (X3aAnalyzer *analyzer)
+    : Thread ("AnalyzerThread")
+    , _analyzer (analyzer)
+{}
+
+AnalyzerThread::~AnalyzerThread ()
+{
+    _3a_stats_queue.clear ();
+}
+
+bool
+AnalyzerThread::push_stats (SmartPtr<X3aIspStatistics> &stats)
+{
+    _3a_stats_queue.push (stats);
+    return true;
+}
+
+bool
+AnalyzerThread::started ()
+{
+    XCamReturn ret = XCAM_RETURN_NO_ERROR;
+
+    XCAM_ASSERT (_analyzer);
+    ret = _analyzer->configure_3a ();
+    if (ret != XCAM_RETURN_NO_ERROR) {
+        _analyzer->notify_calculation_failed (NULL, 0, "configure 3a failed");
+        XCAM_LOG_WARNING ("analyzer(%s) configure 3a failed", XCAM_STR(_analyzer->get_name()));
+        return false;
+    }
+
+    return true;
+}
+
+bool
+AnalyzerThread::loop ()
+{
+    const static int32_t timeout = -1;
+    SmartPtr<X3aIspStatistics> stats = _3a_stats_queue.pop (timeout);
+    if (!stats.ptr()) {
+        XCAM_LOG_DEBUG ("analyzer thread got empty stats, stop thread");
+        return false;
+    }
+    XCamReturn ret = _analyzer->analyze_3a_statistics (stats);
+    if (ret == XCAM_RETURN_NO_ERROR || ret == XCAM_RETURN_BYPASS)
+        return true;
+
+    XCAM_LOG_DEBUG ("analyzer(%s) failed to analyze 3a stats", XCAM_STR(_analyzer->get_name()));
+    return false;
+}
+
+void
+AnalyzerCallback::x3a_calculation_done (X3aAnalyzer *analyzer, X3aResultList &results)
+{
+    XCAM_UNUSED (analyzer);
+
+    for (X3aResultList::iterator i_res = results.begin();
+            i_res != results.end(); ++i_res) {
+        SmartPtr<X3aResult> res = *i_res;
+        XCAM_LOG_DEBUG (
+            "calculated 3a result(type:%d, timestamp:" XCAM_TIMESTAMP_FORMAT ")",
+            res->get_type (), XCAM_TIMESTAMP_ARGS (res->get_timestamp ()));
+    }
+}
+
+void
+AnalyzerCallback::x3a_calculation_failed (X3aAnalyzer *analyzer, int64_t timestamp, const char *msg)
+{
+    XCAM_UNUSED (analyzer);
+
+    XCAM_LOG_WARNING (
+        "Calculate 3a result failed, ts(" XCAM_TIMESTAMP_FORMAT "), msg:%s",
+        XCAM_TIMESTAMP_ARGS (timestamp), XCAM_STR (msg));
+}
+
+X3aAnalyzer::X3aAnalyzer (const char *name)
+    : _name (NULL)
+    , _width (0)
+    , _height (0)
+    , _ae_handler (NULL)
+    , _awb_handler (NULL)
+    , _af_handler (NULL)
+    , _common_handler (NULL)
+    , _callback (NULL)
+{
+    if (name)
+        _name = strdup (name);
+    _3a_analyzer_thread  = new AnalyzerThread (this);
+}
+
+X3aAnalyzer::~X3aAnalyzer()
+{
+    if (_name)
+        xcam_free (_name);
+}
+
+bool
+X3aAnalyzer::set_results_callback (AnalyzerCallback *callback)
+{
+    XCAM_ASSERT (!_callback);
+    _callback = callback;
+    return true;
+}
+
+XCamReturn
+X3aAnalyzer::init (uint32_t width, uint32_t height)
+{
+    XCamReturn ret = XCAM_RETURN_NO_ERROR;
+    SmartPtr<AeHandler> ae_handler;
+    SmartPtr<AwbHandler> awb_handler;
+    SmartPtr<AfHandler> af_handler;
+    SmartPtr<CommonHandler> common_handler;
+
+
+    XCAM_ASSERT (!_width && !_height);
+    _width = width;
+    _height = height;
+
+    XCAM_ASSERT (!_ae_handler.ptr() || !_awb_handler.ptr() ||
+                 !_af_handler.ptr() || !_common_handler.ptr());
+
+    ae_handler = create_ae_handler ();
+    awb_handler = create_awb_handler ();
+    af_handler = create_af_handler ();
+    common_handler = create_common_handler ();
+
+    if (!ae_handler.ptr() || !awb_handler.ptr() || !af_handler.ptr() || !common_handler.ptr()) {
+        XCAM_LOG_WARNING ("create handlers failed");
+        deinit ();
+        return XCAM_RETURN_ERROR_MEM;
+    }
+    _ae_handler = ae_handler;
+    _awb_handler = awb_handler;
+    _af_handler = af_handler;
+    _common_handler = common_handler;
+
+    ret = internal_init (width, height);
+    if (ret != XCAM_RETURN_NO_ERROR) {
+        XCAM_LOG_WARNING ("analyzer init failed");
+        deinit ();
+        return ret;
+    }
+
+    XCAM_LOG_INFO (
+        "Analyzer(%s) initialized(w:%d, h:%d).",
+        XCAM_STR(get_name()), _width, _height);
+    return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+X3aAnalyzer::deinit ()
+{
+    internal_deinit();
+
+    _ae_handler.release ();
+    _awb_handler.release ();
+    _af_handler.release ();
+    _common_handler.release ();
+
+    _width = 0;
+    _height = 0;
+
+    XCAM_LOG_INFO ("Analyzer(%s) deinited.", XCAM_STR(get_name()));
+    return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+X3aAnalyzer::start ()
+{
+    if (_3a_analyzer_thread->start () == false) {
+        XCAM_LOG_WARNING ("analyzer thread start failed");
+        stop ();
+        return XCAM_RETURN_ERROR_THREAD;
+    }
+
+    XCAM_LOG_INFO ("Analyzer(%s) started.", XCAM_STR(get_name()));
+    return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+X3aAnalyzer::stop ()
+{
+    _3a_analyzer_thread->triger_stop ();
+    _3a_analyzer_thread->stop ();
+
+    XCAM_LOG_INFO ("Analyzer(%s) stopped.", XCAM_STR(get_name()));
+    return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+X3aAnalyzer::push_3a_stats (SmartPtr<X3aIspStatistics> &stats)
+{
+    if (!_3a_analyzer_thread->is_running())
+        return XCAM_RETURN_ERROR_THREAD;
+
+    if (_3a_analyzer_thread->push_stats (stats))
+        return XCAM_RETURN_NO_ERROR;
+
+    return XCAM_RETURN_ERROR_THREAD;
+}
+
+XCamReturn
+X3aAnalyzer::analyze_3a_statistics (SmartPtr<X3aIspStatistics> &stats)
+{
+    XCamReturn ret = XCAM_RETURN_NO_ERROR;
+    X3aResultList results;
+
+    ret = pre_3a_analyze (stats);
+    if (ret != XCAM_RETURN_NO_ERROR) {
+        notify_calculation_failed(
+            NULL, stats->get_timestamp (), "ae calculation failed");
+        return ret;
+    }
+
+    ret = _ae_handler->analyze (results);
+    if (ret != XCAM_RETURN_NO_ERROR) {
+        notify_calculation_failed(
+            _ae_handler.ptr(), stats->get_timestamp (), "ae calculation failed");
+        return ret;
+    }
+
+    ret = _awb_handler->analyze (results);
+    if (ret != XCAM_RETURN_NO_ERROR) {
+        notify_calculation_failed(
+            _awb_handler.ptr(), stats->get_timestamp (), "awb calculation failed");
+        return ret;
+    }
+
+    ret = _af_handler->analyze (results);
+    if (ret != XCAM_RETURN_NO_ERROR) {
+        notify_calculation_failed(
+            _af_handler.ptr(), stats->get_timestamp (), "af calculation failed");
+        return ret;
+    }
+
+    ret = _common_handler->analyze (results);
+    if (ret != XCAM_RETURN_NO_ERROR) {
+        notify_calculation_failed(
+            _common_handler.ptr(), stats->get_timestamp (), "3a other calculation failed");
+        return ret;
+    }
+
+    ret = post_3a_analyze (results);
+    if (ret != XCAM_RETURN_NO_ERROR) {
+        notify_calculation_failed(
+            NULL, stats->get_timestamp (), "3a collect results failed");
+        return ret;
+    }
+
+    if (!results.empty ())
+        notify_calculation_done (results);
+
+    return ret;
+
+}
+
+void
+X3aAnalyzer::notify_calculation_failed (AnalyzerHandler *handler, int64_t timestamp, const char *msg)
+{
+    XCAM_UNUSED (handler);
+
+    if (_callback)
+        _callback->x3a_calculation_failed (this, timestamp, msg);
+    XCAM_LOG_DEBUG (
+        "calculation failed on ts:" XCAM_TIMESTAMP_FORMAT ", reason:%s",
+        XCAM_TIMESTAMP_ARGS (timestamp), XCAM_STR (msg));
+}
+
+void
+X3aAnalyzer::notify_calculation_done (X3aResultList &results)
+{
+    XCAM_ASSERT (!results.empty ());
+    if (_callback)
+        _callback->x3a_calculation_done (this, results);
+}
+
+/* AWB */
+bool
+X3aAnalyzer::set_awb_mode (XCamAwbMode mode)
+{
+    XCAM_ASSERT (_awb_handler.ptr());
+    return _awb_handler->set_mode (mode);
+}
+
+bool
+X3aAnalyzer::set_awb_speed (double speed)
+{
+    XCAM_ASSERT (_awb_handler.ptr());
+    return _awb_handler->set_speed (speed);
+}
+
+bool
+X3aAnalyzer::set_awb_color_temperature_range (uint32_t cct_min, uint32_t cct_max)
+{
+    XCAM_ASSERT (_awb_handler.ptr());
+    return _awb_handler->set_color_temperature_range (cct_min, cct_max);
+}
+
+bool
+X3aAnalyzer::set_awb_manual_gain (double gr, double r, double b, double gb)
+{
+    XCAM_ASSERT (_awb_handler.ptr());
+    return _awb_handler->set_manual_gain (gr, r, b, gb);
+}
+
+/* AE */
+bool
+X3aAnalyzer::set_ae_mode (XCamAeMode mode)
+{
+    XCAM_ASSERT (_ae_handler.ptr());
+    return _ae_handler->set_mode (mode);
+}
+
+bool
+X3aAnalyzer::set_ae_metering_mode (XCamAeMeteringMode mode)
+{
+    XCAM_ASSERT (_ae_handler.ptr());
+    return _ae_handler->set_metering_mode (mode);
+}
+
+bool
+X3aAnalyzer::set_ae_window (XCam3AWindow *window)
+{
+    XCAM_ASSERT (_ae_handler.ptr());
+    return _ae_handler->set_window (window);
+}
+
+bool
+X3aAnalyzer::set_ae_ev_shift (double ev_shift)
+{
+    XCAM_ASSERT (_ae_handler.ptr());
+    return _ae_handler->set_ev_shift (ev_shift);
+}
+
+bool
+X3aAnalyzer::set_ae_speed (double speed)
+{
+    XCAM_ASSERT (_ae_handler.ptr());
+    return _ae_handler->set_speed (speed);
+}
+
+bool
+X3aAnalyzer::set_ae_flicker_mode (XCamFlickerMode flicker)
+{
+    XCAM_ASSERT (_ae_handler.ptr());
+    return _ae_handler->set_flicker_mode (flicker);
+}
+
+XCamFlickerMode
+X3aAnalyzer::get_ae_flicker_mode ()
+{
+    XCAM_ASSERT (_ae_handler.ptr());
+    return _ae_handler->get_flicker_mode ();
+}
+
+uint64_t
+X3aAnalyzer::get_ae_current_exposure_time ()
+{
+    XCAM_ASSERT (_ae_handler.ptr());
+    return _ae_handler->get_current_exposure_time();
+}
+
+double
+X3aAnalyzer::get_ae_current_analog_gain ()
+{
+    XCAM_ASSERT (_ae_handler.ptr());
+    return _ae_handler->get_current_analog_gain ();
+}
+
+bool
+X3aAnalyzer::set_ae_manual_exposure_time (int64_t time_in_us)
+{
+    XCAM_ASSERT (_ae_handler.ptr());
+    return _ae_handler->set_manual_exposure_time (time_in_us);
+}
+
+bool
+X3aAnalyzer::set_ae_manual_analog_gain (double gain)
+{
+    XCAM_ASSERT (_ae_handler.ptr());
+    return _ae_handler->set_manual_analog_gain (gain);
+}
+
+bool
+X3aAnalyzer::set_ae_aperture (double fn)
+{
+    XCAM_ASSERT (_ae_handler.ptr());
+    return _ae_handler->set_aperture (fn);
+}
+
+bool
+X3aAnalyzer::set_ae_max_analog_gain (double max_gain)
+{
+    XCAM_ASSERT (_ae_handler.ptr());
+    return _ae_handler->set_max_analog_gain (max_gain);
+}
+
+double
+X3aAnalyzer::get_ae_max_analog_gain ()
+{
+    XCAM_ASSERT (_ae_handler.ptr());
+    return _ae_handler->get_max_analog_gain();
+}
+
+bool
+X3aAnalyzer::set_ae_exposure_time_range (int64_t min_time_in_us, int64_t max_time_in_us)
+{
+    XCAM_ASSERT (_ae_handler.ptr());
+    return _ae_handler->set_exposure_time_range (min_time_in_us, max_time_in_us);
+}
+
+bool
+X3aAnalyzer::get_ae_exposure_time_range (int64_t *min_time_in_us, int64_t *max_time_in_us)
+{
+    XCAM_ASSERT (_ae_handler.ptr());
+    return _ae_handler->get_exposure_time_range (min_time_in_us, max_time_in_us);
+}
+
+/* DVS */
+bool
+X3aAnalyzer::set_dvs (bool enable)
+{
+    XCAM_ASSERT (_common_handler.ptr());
+    return _common_handler->set_dvs (enable);
+}
+
+bool
+X3aAnalyzer::set_gbce (bool enable)
+{
+    XCAM_ASSERT (_common_handler.ptr());
+    return _common_handler->set_gbce (enable);
+}
+
+bool
+X3aAnalyzer::set_night_mode (bool enable)
+{
+    XCAM_ASSERT (_common_handler.ptr());
+    return _common_handler->set_night_mode (enable);
+}
+
+/* Picture quality */
+bool
+X3aAnalyzer::set_noise_reduction_level (double level)
+{
+    XCAM_ASSERT (_common_handler.ptr());
+    return _common_handler->set_noise_reduction_level (level);
+}
+
+bool
+X3aAnalyzer::set_temporal_noise_reduction_level (double level)
+{
+    XCAM_ASSERT (_common_handler.ptr());
+    return _common_handler->set_temporal_noise_reduction_level (level);
+}
+
+bool
+X3aAnalyzer::set_manual_brightness (double level)
+{
+    XCAM_ASSERT (_common_handler.ptr());
+    return _common_handler->set_manual_brightness (level);
+}
+
+bool
+X3aAnalyzer::set_manual_contrast (double level)
+{
+    XCAM_ASSERT (_common_handler.ptr());
+    return _common_handler->set_manual_contrast (level);
+}
+
+bool
+X3aAnalyzer::set_manual_hue (double level)
+{
+    XCAM_ASSERT (_common_handler.ptr());
+    return _common_handler->set_manual_hue (level);
+}
+
+bool
+X3aAnalyzer::set_manual_saturation (double level)
+{
+    XCAM_ASSERT (_common_handler.ptr());
+    return _common_handler->set_manual_saturation (level);
+}
+
+bool
+X3aAnalyzer::set_manual_sharpness (double level)
+{
+    XCAM_ASSERT (_common_handler.ptr());
+    return _common_handler->set_manual_sharpness (level);
+}
+
+bool
+X3aAnalyzer::set_gamma_table (double *r_table, double *g_table, double *b_table)
+{
+    XCAM_ASSERT (_common_handler.ptr());
+    return _common_handler->set_gamma_table (r_table, g_table, b_table);
+}
+
+};
diff --git a/xcore/x3a_analyzer.h b/xcore/x3a_analyzer.h
new file mode 100644
index 0000000..5173b5d
--- /dev/null
+++ b/xcore/x3a_analyzer.h
@@ -0,0 +1,168 @@
+/*
+ * x3a_analyzer.h - 3a analyzer
+ *
+ *  Copyright (c) 2014-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: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#ifndef XCAM_3A_ANALYZER_H
+#define XCAM_3A_ANALYZER_H
+
+#include "xcam_common.h"
+#include "xcam_defs.h"
+#include "xcam_utils.h"
+#include "handler_interface.h"
+
+namespace XCam {
+
+class X3aAnalyzer;
+class X3aIspStatistics;
+
+class AnalyzerCallback {
+public:
+    explicit AnalyzerCallback () {}
+    virtual ~AnalyzerCallback () {}
+    virtual void x3a_calculation_done (X3aAnalyzer *analyzer, X3aResultList &results);
+    virtual void x3a_calculation_failed (X3aAnalyzer *analyzer, int64_t timestamp, const char *msg);
+
+private:
+    XCAM_DEAD_COPY (AnalyzerCallback);
+};
+
+class AnalyzerThread;
+
+class X3aAnalyzer {
+    friend class AnalyzerThread;
+public:
+    explicit X3aAnalyzer (const char *name = NULL);
+    virtual ~X3aAnalyzer ();
+
+    bool set_results_callback (AnalyzerCallback *callback);
+
+    XCamReturn init (uint32_t width, uint32_t height);
+    XCamReturn deinit ();
+    XCamReturn start ();
+    XCamReturn stop ();
+
+    /* analyze 3A statistics */
+    XCamReturn push_3a_stats (SmartPtr<X3aIspStatistics> &stats);
+
+    /* AWB */
+    bool set_awb_mode (XCamAwbMode mode);
+    bool set_awb_speed (double speed);
+    bool set_awb_color_temperature_range (uint32_t cct_min, uint32_t cct_max);
+    bool set_awb_manual_gain (double gr, double r, double b, double gb);
+
+    /* AE */
+    bool set_ae_mode (XCamAeMode mode);
+    bool set_ae_metering_mode (XCamAeMeteringMode mode);
+    bool set_ae_window (XCam3AWindow *window);
+    bool set_ae_ev_shift (double ev_shift);
+    bool set_ae_speed (double speed);
+    bool set_ae_flicker_mode (XCamFlickerMode flicker);
+
+    XCamFlickerMode get_ae_flicker_mode ();
+    uint64_t get_ae_current_exposure_time ();
+    double get_ae_current_analog_gain ();
+
+    bool set_ae_manual_exposure_time (int64_t time_in_us);
+    bool set_ae_manual_analog_gain (double gain);
+    bool set_ae_aperture (double fn);
+    bool set_ae_max_analog_gain (double max_gain);
+    double get_ae_max_analog_gain ();
+    bool set_ae_exposure_time_range (int64_t min_time_in_us, int64_t max_time_in_us);
+    bool get_ae_exposure_time_range (int64_t *min_time_in_us, int64_t *max_time_in_us);
+
+    /* DVS */
+    bool set_dvs (bool enable);
+    bool set_gbce (bool enable);
+    bool set_night_mode (bool enable);
+
+    /* Picture quality */
+    bool set_noise_reduction_level (double level);
+    bool set_temporal_noise_reduction_level (double level);
+    bool set_manual_brightness (double level);
+    bool set_manual_contrast (double level);
+    bool set_manual_hue (double level);
+    bool set_manual_saturation (double level);
+    bool set_manual_sharpness (double level);
+    bool set_gamma_table (double *r_table, double *g_table, double *b_table);
+
+    uint32_t get_width () const {
+        return _width;
+    }
+    uint32_t get_height () const {
+        return _height;
+    }
+    const char * get_name () const {
+        return _name;
+    }
+
+    SmartPtr<AeHandler> get_ae_handler () {
+        return _ae_handler;
+    }
+    SmartPtr<AwbHandler> get_awb_handler () {
+        return _awb_handler;
+    }
+    SmartPtr<AfHandler> get_af_handler () {
+        return _af_handler;
+    }
+    SmartPtr<CommonHandler> get_common_handler () {
+        return _common_handler;
+    }
+
+protected:
+    /* virtual function list */
+    virtual SmartPtr<AeHandler> create_ae_handler () = 0;
+    virtual SmartPtr<AwbHandler> create_awb_handler () = 0;
+    virtual SmartPtr<AfHandler> create_af_handler () = 0;
+    virtual SmartPtr<CommonHandler> create_common_handler () = 0;
+    virtual XCamReturn internal_init (uint32_t width, uint32_t height) = 0;
+    virtual XCamReturn internal_deinit () = 0;
+
+    // in 3a stats thread
+    virtual XCamReturn configure_3a () = 0;
+    // @param[in]   stats,  3a statistics prepared
+    virtual XCamReturn pre_3a_analyze (SmartPtr<X3aIspStatistics> &stats) = 0;
+    // @param[out]  results,   new 3a results merged into \c results
+    virtual XCamReturn post_3a_analyze (X3aResultList &results) = 0;
+
+protected:
+    void notify_calculation_done (X3aResultList &results);
+    void notify_calculation_failed (AnalyzerHandler *handler, int64_t timestamp, const char *msg);
+
+private:
+    XCamReturn analyze_3a_statistics (SmartPtr<X3aIspStatistics> &stats);
+
+    XCAM_DEAD_COPY (X3aAnalyzer);
+
+private:
+    char                    *_name;
+    uint32_t                 _width;
+    uint32_t                 _height;
+
+    SmartPtr<AeHandler>      _ae_handler;
+    SmartPtr<AwbHandler>     _awb_handler;
+    SmartPtr<AfHandler>      _af_handler;
+    SmartPtr<CommonHandler>  _common_handler;
+
+    SmartPtr<AnalyzerThread> _3a_analyzer_thread;
+    AnalyzerCallback        *_callback;
+
+};
+
+}
+#endif //XCAM_3A_ANALYZER_H
diff --git a/xcore/x3a_analyzer_aiq.cpp b/xcore/x3a_analyzer_aiq.cpp
new file mode 100644
index 0000000..dd5ae6b
--- /dev/null
+++ b/xcore/x3a_analyzer_aiq.cpp
@@ -0,0 +1,239 @@
+/*
+ * x3a_analyzer_aiq.h - 3a analyzer from AIQ
+ *
+ *  Copyright (c) 2014-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: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#include "x3a_analyzer_aiq.h"
+#include "aiq_handler.h"
+#include "isp_controller.h"
+#include "xcam_cpf_reader.h"
+#include "ia_types.h"
+
+namespace XCam {
+
+class CpfReader {
+public:
+    explicit CpfReader (const char *name);
+    ~CpfReader();
+    bool read (ia_binary_data &binary);
+private:
+    XCamCpfBlob *_aiq_cpf;
+    char *_name;
+};
+
+CpfReader::CpfReader (const char *name)
+    : _name (strdup(name))
+{
+    _aiq_cpf = xcam_cpf_blob_new ();
+    XCAM_ASSERT (name);
+}
+CpfReader::~CpfReader()
+{
+    if (_aiq_cpf)
+        xcam_cpf_blob_free (_aiq_cpf);
+    if (_name)
+        xcam_free (_name);
+}
+
+bool CpfReader::read (ia_binary_data &binary)
+{
+    if (!xcam_cpf_read (_name, _aiq_cpf, NULL)) {
+        XCAM_LOG_ERROR ("parse CPF(%s) failed", XCAM_STR (_name));
+        return false;
+    }
+    binary.data  = _aiq_cpf->data;
+    binary.size = _aiq_cpf->size;
+    XCAM_LOG_INFO ("read cpf(%s) ok", XCAM_STR (_name));
+    return true;
+}
+
+X3aAnalyzerAiq::X3aAnalyzerAiq (SmartPtr<IspController> &isp, const char *cpf_path)
+    : X3aAnalyzer ("X3aAnalyzerAiq")
+    , _isp (isp)
+    , _cpf_path (NULL)
+{
+    if (cpf_path)
+        _cpf_path = strdup (cpf_path);
+
+    _aiq_compositor = new AiqCompositor ();
+    XCAM_ASSERT (_aiq_compositor.ptr());
+    xcam_mem_clear (&_sensor_mode_data);
+
+    XCAM_LOG_DEBUG ("X3aAnalyzerAiq constructed");
+}
+
+X3aAnalyzerAiq::~X3aAnalyzerAiq()
+{
+    if (_cpf_path)
+        xcam_free (_cpf_path);
+
+    XCAM_LOG_DEBUG ("~X3aAnalyzerAiq destructed");
+}
+
+SmartPtr<AeHandler>
+X3aAnalyzerAiq::create_ae_handler ()
+{
+
+    SmartPtr<AiqAeHandler> ae_handler = new AiqAeHandler (_aiq_compositor);
+    _aiq_compositor->set_ae_handler (ae_handler);
+    return ae_handler;
+}
+
+SmartPtr<AwbHandler>
+X3aAnalyzerAiq::create_awb_handler ()
+{
+    SmartPtr<AiqAwbHandler> awb_handler = new AiqAwbHandler (_aiq_compositor);
+    _aiq_compositor->set_awb_handler (awb_handler);
+    return awb_handler;
+}
+
+SmartPtr<AfHandler>
+X3aAnalyzerAiq::create_af_handler ()
+{
+
+    SmartPtr<AiqAfHandler> af_handler = new AiqAfHandler (_aiq_compositor);
+    _aiq_compositor->set_af_handler (af_handler);
+    return af_handler;
+}
+
+SmartPtr<CommonHandler>
+X3aAnalyzerAiq::create_common_handler ()
+{
+    SmartPtr<AiqCommonHandler> common_handler = new AiqCommonHandler (_aiq_compositor);
+    _aiq_compositor->set_common_handler (common_handler);
+    return common_handler;
+}
+
+XCamReturn
+X3aAnalyzerAiq::internal_init (uint32_t width, uint32_t height)
+{
+    XCAM_ASSERT (_cpf_path);
+    CpfReader reader (_cpf_path);
+    ia_binary_data binary;
+
+    XCAM_ASSERT (_aiq_compositor.ptr());
+
+    xcam_mem_clear (&binary);
+    XCAM_FAIL_RETURN (
+        ERROR,
+        reader.read(binary),
+        XCAM_RETURN_ERROR_AIQ,
+        "read cpf file(%s) failed", _cpf_path);
+
+    _aiq_compositor->set_size (width, height);
+    XCAM_FAIL_RETURN (
+        ERROR,
+        _aiq_compositor->open (binary),
+        XCAM_RETURN_ERROR_AIQ,
+        "AIQ open failed");
+
+    return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+X3aAnalyzerAiq::internal_deinit ()
+{
+    if (_aiq_compositor.ptr ())
+        _aiq_compositor->close ();
+
+    return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+X3aAnalyzerAiq::configure_3a ()
+{
+    XCamReturn ret = XCAM_RETURN_NO_ERROR;
+    X3aResultList first_results;
+    struct atomisp_sensor_mode_data sensor_mode_data;
+    xcam_mem_clear (&sensor_mode_data);
+
+    XCAM_ASSERT (_isp.ptr());
+    xcam_mem_clear (&sensor_mode_data);
+
+    ret = _isp->get_sensor_mode_data (sensor_mode_data);
+    XCAM_FAIL_RETURN (WARNING, ret == XCAM_RETURN_NO_ERROR, ret, "get sensor mode data failed");
+
+    if (!_aiq_compositor->set_sensor_mode_data (&sensor_mode_data)) {
+        XCAM_LOG_WARNING ("AIQ configure 3a failed");
+        return XCAM_RETURN_ERROR_AIQ;
+    }
+
+    XCAM_LOG_DEBUG ("X3aAnalyzerAiq got sensor mode data, coarse_time_min:%u, "
+                    "coarse_time_max_margin:%u, "
+                    "fine_time_min:%u, fine_time_max_margin:%u, "
+                    "fine_time_def:%u, "
+                    "frame_length_lines:%u, line_length_pck:%u, "
+                    "vt_pix_clk_freq_mhz:%u, "
+                    "crop_horizontal_start:%u, crop_vertical_start:%u, "
+                    "crop_horizontal_end:%u, crop_vertical_end:%u, "
+                    "output_width:%u, output_height:%u, "
+                    "binning_factor_x:%u, binning_factor_y:%u",
+                    sensor_mode_data.coarse_integration_time_min,
+                    sensor_mode_data.coarse_integration_time_max_margin,
+                    sensor_mode_data.fine_integration_time_min,
+                    sensor_mode_data.fine_integration_time_max_margin,
+                    sensor_mode_data.fine_integration_time_def,
+                    sensor_mode_data.frame_length_lines,
+                    sensor_mode_data.line_length_pck,
+                    sensor_mode_data.vt_pix_clk_freq_mhz,
+                    sensor_mode_data.crop_horizontal_start,
+                    sensor_mode_data.crop_vertical_start,
+                    sensor_mode_data.crop_horizontal_end,
+                    sensor_mode_data.crop_vertical_end,
+                    sensor_mode_data.output_width,
+                    sensor_mode_data.output_height,
+                    (uint32_t)sensor_mode_data.binning_factor_x,
+                    (uint32_t)sensor_mode_data.binning_factor_y);
+
+    // initialize ae and awb
+    get_ae_handler ()->analyze (first_results);
+    get_awb_handler ()->analyze (first_results);
+
+    ret = _aiq_compositor->integrate (first_results);
+    XCAM_FAIL_RETURN (WARNING, ret == XCAM_RETURN_NO_ERROR, ret, "AIQ configure_3a failed on integrate results");
+
+    if (!first_results.empty()) {
+        notify_calculation_done (first_results);
+    }
+
+    return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+X3aAnalyzerAiq::pre_3a_analyze (SmartPtr<X3aIspStatistics> &stats)
+{
+    if (!_aiq_compositor->set_3a_stats (stats)) {
+        XCAM_LOG_WARNING ("Aiq compositor set 3a stats failed");
+        return XCAM_RETURN_ERROR_UNKNOWN;
+    }
+
+    return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+X3aAnalyzerAiq::post_3a_analyze (X3aResultList &results)
+{
+    XCamReturn ret = XCAM_RETURN_NO_ERROR;
+
+    ret = _aiq_compositor->integrate (results);
+    XCAM_FAIL_RETURN (WARNING, ret == XCAM_RETURN_NO_ERROR, ret, "AIQ integrate 3A results failed");
+
+    return XCAM_RETURN_NO_ERROR;
+}
+
+};
diff --git a/xcore/x3a_analyzer_aiq.h b/xcore/x3a_analyzer_aiq.h
new file mode 100644
index 0000000..5cc1687
--- /dev/null
+++ b/xcore/x3a_analyzer_aiq.h
@@ -0,0 +1,68 @@
+/*
+ * x3a_analyzer_aiq.h - 3a analyzer from AIQ
+ *
+ *  Copyright (c) 2014-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: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#ifndef XCAM_3A_ANALYZER_AIQ_H
+#define XCAM_3A_ANALYZER_AIQ_H
+
+#include "xcam_common.h"
+#include "xcam_defs.h"
+#include "xcam_utils.h"
+#include "x3a_analyzer.h"
+#include <linux/atomisp.h>
+
+namespace XCam {
+
+class AiqCompositor;
+class IspController;
+
+class X3aAnalyzerAiq
+    : public X3aAnalyzer
+{
+public:
+    explicit X3aAnalyzerAiq (SmartPtr<IspController> &isp, const char *cpf_path);
+    ~X3aAnalyzerAiq ();
+
+private:
+
+    XCAM_DEAD_COPY (X3aAnalyzerAiq);
+
+protected:
+    virtual SmartPtr<AeHandler> create_ae_handler ();
+    virtual SmartPtr<AwbHandler> create_awb_handler ();
+    virtual SmartPtr<AfHandler> create_af_handler ();
+    virtual SmartPtr<CommonHandler> create_common_handler ();
+
+    virtual XCamReturn internal_init (uint32_t width, uint32_t height);
+    virtual XCamReturn internal_deinit ();
+
+    virtual XCamReturn configure_3a ();
+    virtual XCamReturn pre_3a_analyze (SmartPtr<X3aIspStatistics> &stats);
+    virtual XCamReturn post_3a_analyze (X3aResultList &results);
+
+private:
+    SmartPtr <AiqCompositor>          _aiq_compositor;
+
+    SmartPtr <IspController>          _isp;
+    struct atomisp_sensor_mode_data   _sensor_mode_data;
+    char                             *_cpf_path;
+};
+
+};
+#endif //XCAM_3A_ANALYZER_AIQ_H
diff --git a/xcore/x3a_analyzer_manager.cpp b/xcore/x3a_analyzer_manager.cpp
new file mode 100644
index 0000000..5af82f7
--- /dev/null
+++ b/xcore/x3a_analyzer_manager.cpp
@@ -0,0 +1,115 @@
+/*
+ * x3a_analyzer_manager.cpp - analyzer manager
+ *
+ *  Copyright (c) 2014-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: Wind Yuan <feng.yuan@intel.com>
+ */
+
+
+#include "x3a_analyzer_manager.h"
+#include "x3a_analyzer_simple.h"
+#if HAVE_IA_AIQ
+#include "x3a_analyzer_aiq.h"
+#endif
+
+#include <sys/types.h>
+#include <dirent.h>
+
+namespace XCam {
+
+#define XCAM_DEFAULT_3A_LIB_DIR "/usr/lib/xcam"
+
+SmartPtr<X3aAnalyzerManager> X3aAnalyzerManager::_instance(NULL);
+Mutex X3aAnalyzerManager::_mutex;
+
+SmartPtr<X3aAnalyzerManager>
+X3aAnalyzerManager::instance()
+{
+    SmartLock lock(_mutex);
+    if (_instance.ptr())
+        return _instance;
+    _instance = new X3aAnalyzerManager;
+    return _instance;
+}
+
+X3aAnalyzerManager::X3aAnalyzerManager ()
+{
+    XCAM_LOG_DEBUG ("X3aAnalyzerManager construction");
+}
+X3aAnalyzerManager::~X3aAnalyzerManager ()
+{
+    XCAM_LOG_DEBUG ("X3aAnalyzerManager destruction");
+}
+
+SmartPtr<X3aAnalyzer>
+X3aAnalyzerManager::create_analyzer()
+{
+    SmartPtr<X3aAnalyzer> analyzer = find_analyzer();
+    if (!analyzer.ptr())
+        analyzer = new X3aAnalyzerSimple;
+    return analyzer;
+}
+
+#if 0
+/* C interface of 3A lib */
+typedef struct _XCam3ADescription {
+    XCamReturn (*run_awb) (XCamAwbParams *params, uint64_t timestamp);
+    XCamReturn (*run_awb) (XCamAwbParams *params, uint64_t timestamp);
+    XCamReturn (*run_awb) (XCamAwbParams *params, uint64_t timestamp);
+    XCamReturn (*get_combined_result) (XCam3aResultList *results , uint64_t *timestamp);
+} XCam3ADescription;
+#endif
+
+SmartPtr<X3aAnalyzer>
+X3aAnalyzerManager::find_analyzer ()
+{
+    char lib_path[512];
+    const char *dir_path = NULL;
+    DIR  *dir_3a = NULL;
+    struct dirent *dirent_3a = NULL;
+    SmartPtr<X3aAnalyzer> analyzer;
+
+    dir_path = getenv ("XCAM_3A_LIB");
+    if (!dir_path) {
+        dir_path = XCAM_DEFAULT_3A_LIB_DIR;
+    }
+    dir_3a = opendir (dir_path);
+    if (dir_3a) {
+        while ((dirent_3a = readdir (dir_3a)) != NULL) {
+            if (dirent_3a->d_type != DT_LNK &&
+                    dirent_3a->d_type != DT_REG)
+                continue;
+            snprintf (lib_path, sizeof(lib_path), "%s/%s", dir_path, dirent_3a->d_name);
+            analyzer = load_analyzer_from_binary (lib_path);
+            if (analyzer.ptr())
+                break;
+        }
+    }
+    if (dir_3a)
+        closedir (dir_3a);
+    return analyzer;
+}
+
+SmartPtr<X3aAnalyzer>
+X3aAnalyzerManager::load_analyzer_from_binary (const char *path)
+{
+    SmartPtr<X3aAnalyzer> loaded_analyzer;
+    // TODO
+    return loaded_analyzer;
+}
+
+};
+
diff --git a/xcore/x3a_analyzer_manager.h b/xcore/x3a_analyzer_manager.h
new file mode 100644
index 0000000..2fb99f1
--- /dev/null
+++ b/xcore/x3a_analyzer_manager.h
@@ -0,0 +1,51 @@
+/*
+ * x3a_analyzer_manager.h - analyzer manager
+ *
+ *  Copyright (c) 2014-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: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#ifndef XCAM_3A_ANALYZER_MANAGER_H
+#define XCAM_3A_ANALYZER_MANAGER_H
+
+#include "x3a_analyzer.h"
+
+namespace XCam {
+
+class X3aAnalyzerManager
+{
+protected:
+    explicit X3aAnalyzerManager ();
+public:
+    virtual ~X3aAnalyzerManager ();
+
+    static SmartPtr<X3aAnalyzerManager> instance();
+
+    virtual SmartPtr<X3aAnalyzer> create_analyzer();
+
+private:
+    SmartPtr<X3aAnalyzer> find_analyzer ();
+    SmartPtr<X3aAnalyzer> load_analyzer_from_binary (const char *path);
+
+private:
+    XCAM_DEAD_COPY (X3aAnalyzerManager);
+
+private:
+    static SmartPtr<X3aAnalyzerManager> _instance;
+    static Mutex                        _mutex;
+};
+};
+#endif //XCAM_3A_ANALYZER_MANAGER_H
diff --git a/xcore/x3a_analyzer_simple.cpp b/xcore/x3a_analyzer_simple.cpp
new file mode 100644
index 0000000..17c4905
--- /dev/null
+++ b/xcore/x3a_analyzer_simple.cpp
@@ -0,0 +1,272 @@
+/*
+ * x3a_analyzer_simple.cpp - a simple 3a analyzer
+ *
+ *  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: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#include "x3a_analyzer_simple.h"
+#include "x3a_statistics_queue.h"
+#include <linux/atomisp.h>
+
+namespace XCam {
+
+#define SIMPLE_MIN_TARGET_EXPOSURE_TIME  5000 //5ms
+#define SIMPLE_MAX_TARGET_EXPOSURE_TIME  33000 //33ms
+#define SIMPLE_DEFAULT_BLACK_LEVEL       0.05
+
+class SimpleAeHandler
+    : public AeHandler
+{
+public:
+    SimpleAeHandler (X3aAnalyzerSimple *analyzer)
+        : _analyzer (analyzer)
+    {}
+    ~SimpleAeHandler () {}
+
+    virtual XCamReturn analyze (X3aResultList &output) {
+        return _analyzer->analyze_ae (output);
+    }
+private:
+    X3aAnalyzerSimple *_analyzer;
+};
+
+class SimpleAwbHandler
+    : public AwbHandler
+{
+public:
+    SimpleAwbHandler (X3aAnalyzerSimple *analyzer)
+        : _analyzer (analyzer)
+    {}
+    ~SimpleAwbHandler () {}
+
+    virtual XCamReturn analyze (X3aResultList &output) {
+        return _analyzer->analyze_awb (output);
+    }
+private:
+    X3aAnalyzerSimple *_analyzer;
+
+};
+
+class SimpleAfHandler
+    : public AfHandler
+{
+public:
+    SimpleAfHandler (X3aAnalyzerSimple *analyzer)
+        : _analyzer (analyzer)
+    {}
+    ~SimpleAfHandler () {}
+
+    virtual XCamReturn analyze (X3aResultList &output) {
+        return _analyzer->analyze_af (output);
+    }
+
+private:
+    X3aAnalyzerSimple *_analyzer;
+};
+
+class SimpleCommonHandler
+    : public CommonHandler
+{
+public:
+    SimpleCommonHandler (X3aAnalyzerSimple *analyzer)
+        : _analyzer (analyzer)
+    {}
+    ~SimpleCommonHandler () {}
+
+    virtual XCamReturn analyze (X3aResultList &output) {
+        XCAM_UNUSED (output);
+        return XCAM_RETURN_NO_ERROR;
+    }
+
+private:
+    X3aAnalyzerSimple *_analyzer;
+};
+
+X3aAnalyzerSimple::X3aAnalyzerSimple ()
+    : X3aAnalyzer ("X3aAnalyzerSimple")
+    , _last_target_exposure ((double)SIMPLE_MIN_TARGET_EXPOSURE_TIME)
+    , _is_ae_started (false)
+{
+}
+
+X3aAnalyzerSimple::~X3aAnalyzerSimple ()
+{
+}
+
+SmartPtr<AeHandler>
+X3aAnalyzerSimple::create_ae_handler ()
+{
+    SimpleAeHandler *handler = new SimpleAeHandler (this);
+    return handler;
+}
+
+SmartPtr<AwbHandler>
+X3aAnalyzerSimple::create_awb_handler ()
+{
+    SimpleAwbHandler *handler = new SimpleAwbHandler (this);
+    return handler;
+}
+
+SmartPtr<AfHandler>
+X3aAnalyzerSimple::create_af_handler ()
+{
+    SimpleAfHandler *handler = new SimpleAfHandler (this);
+    return handler;
+}
+
+SmartPtr<CommonHandler>
+X3aAnalyzerSimple::create_common_handler ()
+{
+    SimpleCommonHandler *handler = new SimpleCommonHandler (this);
+    return handler;
+}
+
+XCamReturn
+X3aAnalyzerSimple::configure_3a ()
+{
+    _is_ae_started = false;
+    return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+X3aAnalyzerSimple::pre_3a_analyze (SmartPtr<X3aIspStatistics> &stats)
+{
+    _current_stats = stats;
+    return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+X3aAnalyzerSimple::post_3a_analyze (X3aResultList &results)
+{
+    _current_stats.release ();
+
+    XCam3aResultBlackLevel black_level;
+    SmartPtr<X3aBlackLevelResult> bl_result = new X3aBlackLevelResult (XCAM_3A_RESULT_BLACK_LEVEL);
+
+    xcam_mem_clear (&black_level);
+    black_level.r_level = SIMPLE_DEFAULT_BLACK_LEVEL;
+    black_level.gr_level = SIMPLE_DEFAULT_BLACK_LEVEL;
+    black_level.gb_level = SIMPLE_DEFAULT_BLACK_LEVEL;
+    black_level.b_level = SIMPLE_DEFAULT_BLACK_LEVEL;
+    bl_result->set_standard_result (black_level);
+    results.push_back (bl_result);
+
+    return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+X3aAnalyzerSimple::analyze_awb (X3aResultList &output)
+{
+    const struct atomisp_3a_statistics *stats = _current_stats->get_3a_stats ();
+    uint32_t cell_count = stats->grid_info.bqs_per_grid_cell * stats->grid_info.bqs_per_grid_cell;
+    uint32_t bits_depth = stats->grid_info.elem_bit_depth;
+    double sum_r = 0.0, sum_gr = 0.0, sum_gb = 0.0, sum_b = 0.0;
+    double avg_r = 0.0, avg_gr = 0.0, avg_gb = 0.0, avg_b = 0.0;
+    double target_avg = 0.0;
+    XCam3aResultWhiteBalance wb;
+
+    xcam_mem_clear (&wb);
+
+    // calculate avg r, gr, gb, b
+    for (uint32_t i = 0; i < stats->grid_info.height; ++i)
+        for (uint32_t j = 0; j < stats->grid_info.width; ++j) {
+            sum_r += ((double)(stats->data[i * stats->grid_info.width + j].awb_r)) / cell_count;
+            sum_gr += ((double)(stats->data[i * stats->grid_info.width + j].awb_gr)) / cell_count;
+            sum_gb += ((double)(stats->data[i * stats->grid_info.width + j].awb_gb)) / cell_count;
+            sum_b += ((double)(stats->data[i * stats->grid_info.width + j].awb_b)) / cell_count;
+        }
+
+    avg_r = sum_r / (stats->grid_info.width * stats->grid_info.height);
+    avg_gr = sum_gr / (stats->grid_info.width * stats->grid_info.height);
+    avg_gb = sum_gb / (stats->grid_info.width * stats->grid_info.height);
+    avg_b = sum_b / (stats->grid_info.width * stats->grid_info.height);
+    avg_r = avg_r / (1 << (bits_depth - 8));
+    avg_gr = avg_gr / (1 << (bits_depth - 8));
+    avg_gb = avg_gb / (1 << (bits_depth - 8));
+    avg_b = avg_b / (1 << (bits_depth - 8));
+    target_avg =  (avg_gr + avg_gb) / 2;
+    wb.r_gain = target_avg / avg_r;
+    wb.b_gain = target_avg / avg_b;
+    wb.gr_gain = 1.0;
+    wb.gb_gain = 1.0;
+
+    SmartPtr<X3aWhiteBalanceResult> result = new X3aWhiteBalanceResult (XCAM_3A_RESULT_WHITE_BALANCE);
+    result->set_standard_result (wb);
+    output.push_back (result);
+
+    XCAM_LOG_DEBUG ("X3aAnalyzerSimple analyze awb, r:%f, gr:%f, gb:%f, b:%f",
+                    wb.r_gain, wb.gr_gain, wb.gb_gain, wb.b_gain);
+
+    return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+X3aAnalyzerSimple::analyze_ae (X3aResultList &output)
+{
+    static const uint32_t expect_y_mean = 150;
+
+    const struct atomisp_3a_statistics *stats = _current_stats->get_3a_stats ();
+    uint32_t cell_count = stats->grid_info.bqs_per_grid_cell * stats->grid_info.bqs_per_grid_cell;
+    uint32_t bits_depth = stats->grid_info.elem_bit_depth;
+    double sum_y = 0.0;
+    double target_exposure = 1.0;
+    SmartPtr<X3aExposureResult> result = new X3aExposureResult (XCAM_3A_RESULT_EXPOSURE);;
+    XCam3aResultExposure exposure;
+
+    xcam_mem_clear (&exposure);
+    exposure.digital_gain = 1.0;
+
+    if (!_is_ae_started) {
+        _last_target_exposure = SIMPLE_MIN_TARGET_EXPOSURE_TIME;
+        exposure.exposure_time = _last_target_exposure;
+        exposure.analog_gain = 1.0;
+
+        result->set_standard_result (exposure);
+        output.push_back (result);
+        _is_ae_started = true;
+        return XCAM_RETURN_NO_ERROR;
+    }
+
+    for (uint32_t i = 0; i < stats->grid_info.height; ++i)
+        for (uint32_t j = 0; j < stats->grid_info.width; ++j) {
+            sum_y += ((double)(stats->data[i * stats->grid_info.width + j].ae_y)) / cell_count;
+        }
+    sum_y /= (stats->grid_info.width * stats->grid_info.height);
+    sum_y /= (1 << (bits_depth - 8)); // make it in 8 bits
+    target_exposure = (expect_y_mean / sum_y) * _last_target_exposure;
+    target_exposure = XCAM_MAX (target_exposure, SIMPLE_MIN_TARGET_EXPOSURE_TIME);
+
+    if (target_exposure > SIMPLE_MAX_TARGET_EXPOSURE_TIME) {
+        exposure.exposure_time = SIMPLE_MAX_TARGET_EXPOSURE_TIME;
+        exposure.analog_gain = target_exposure / exposure.exposure_time;
+    } else {
+        exposure.exposure_time = target_exposure;
+        exposure.analog_gain = 1.0;
+    }
+    result->set_standard_result (exposure);
+    output.push_back (result);
+
+    return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn X3aAnalyzerSimple::analyze_af (X3aResultList &output)
+{
+    XCAM_UNUSED (output);
+    return XCAM_RETURN_NO_ERROR;
+}
+
+};
diff --git a/xcore/x3a_analyzer_simple.h b/xcore/x3a_analyzer_simple.h
new file mode 100644
index 0000000..91fd7bb
--- /dev/null
+++ b/xcore/x3a_analyzer_simple.h
@@ -0,0 +1,75 @@
+/*
+ * x3a_analyzer_simple.h - a simple 3a analyzer
+ *
+ *  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: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#ifndef XCAM_3A_ANALYZER_SIMPLE_H
+#define XCAM_3A_ANALYZER_SIMPLE_H
+
+#include "xcam_common.h"
+#include "xcam_defs.h"
+#include "xcam_utils.h"
+#include "x3a_analyzer.h"
+#include <linux/atomisp.h>
+
+namespace XCam {
+
+class X3aAnalyzerSimple
+    : public X3aAnalyzer
+{
+public:
+    explicit X3aAnalyzerSimple ();
+    ~X3aAnalyzerSimple ();
+
+private:
+
+    XCAM_DEAD_COPY (X3aAnalyzerSimple);
+
+protected:
+    virtual SmartPtr<AeHandler> create_ae_handler ();
+    virtual SmartPtr<AwbHandler> create_awb_handler ();
+    virtual SmartPtr<AfHandler> create_af_handler ();
+    virtual SmartPtr<CommonHandler> create_common_handler ();
+
+    virtual XCamReturn internal_init (uint32_t width, uint32_t height) {
+        XCAM_UNUSED (width);
+        XCAM_UNUSED (height);
+        return XCAM_RETURN_NO_ERROR;
+    }
+    virtual XCamReturn internal_deinit () {
+        _is_ae_started = false;
+        return XCAM_RETURN_NO_ERROR;
+    }
+    virtual XCamReturn configure_3a ();
+    virtual XCamReturn pre_3a_analyze (SmartPtr<X3aIspStatistics> &stats);
+    virtual XCamReturn post_3a_analyze (X3aResultList &results);
+
+public:
+    XCamReturn analyze_ae (X3aResultList &output);
+    XCamReturn analyze_awb (X3aResultList &output);
+    XCamReturn analyze_af (X3aResultList &output);
+
+private:
+    SmartPtr<X3aIspStatistics>        _current_stats;
+    double                            _last_target_exposure;
+    bool                              _is_ae_started;
+};
+
+};
+#endif //XCAM_3A_ANALYZER_SIMPLE_H
+
diff --git a/xcore/x3a_event.h b/xcore/x3a_event.h
new file mode 100644
index 0000000..f8c7e03
--- /dev/null
+++ b/xcore/x3a_event.h
@@ -0,0 +1,64 @@
+/*
+ * x3a_event.h - event
+ *
+ *  Copyright (c) 2014 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: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#ifndef XCAM_3A_EVENT_H
+#define XCAM_3A_EVENT_H
+
+#include "xcam_defs.h"
+#include "xcam_common.h"
+
+namespace XCam {
+
+class X3aEvent
+    //:public ObjectLife
+{
+public:
+    enum Type {
+        TYPE_ISP_STATISTICS,
+        TYPE_ISP_FRAME_SYNC,
+    };
+
+protected:
+    explicit X3aEvent (X3aEvent::Type type, uint64_t timestamp)
+        : _timestamp (timestamp)
+        , _type (type)
+    {}
+    virtual ~X3aEvent() {}
+
+public:
+    uint64_t get_timestamp () const {
+        return _timestamp;
+    }
+    Type get_type () const {
+        return _type;
+    }
+
+private:
+    XCAM_DEAD_COPY (X3aEvent);
+
+protected:
+    uint64_t       _timestamp;
+    X3aEvent::Type _type;
+};
+
+};
+
+#endif //XCAM_3A_EVENT_H
+
diff --git a/xcore/x3a_image_process_center.cpp b/xcore/x3a_image_process_center.cpp
new file mode 100644
index 0000000..0d6c681
--- /dev/null
+++ b/xcore/x3a_image_process_center.cpp
@@ -0,0 +1,236 @@
+/*
+ * x3a_image_process_center.cpp - 3a process center
+ *
+ *  Copyright (c) 2014-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: Wind Yuan <feng.yuan@intel.com>
+ */
+#include "x3a_image_process_center.h"
+
+namespace XCam {
+
+X3aImageProcessCenter::X3aImageProcessCenter()
+    :   _callback (NULL)
+{
+    XCAM_LOG_DEBUG ("X3aImageProcessCenter construction");
+}
+
+X3aImageProcessCenter::~X3aImageProcessCenter()
+{
+    stop ();
+    XCAM_LOG_DEBUG ("~X3aImageProcessCenter destruction");
+}
+
+bool
+X3aImageProcessCenter::set_image_callback (ImageProcessCallback *callback)
+{
+    XCAM_ASSERT (!_callback);
+    _callback = callback;
+    return true;
+}
+
+bool
+X3aImageProcessCenter::insert_processor (SmartPtr<ImageProcessor> &processor)
+{
+    _image_processors.push_back (processor);
+    XCAM_LOG_INFO ("Add processor(%s) into image processor center", XCAM_STR (processor->get_name()));
+    return true;
+}
+
+bool
+X3aImageProcessCenter::has_processors ()
+{
+    return !_image_processors.empty();
+}
+
+XCamReturn
+X3aImageProcessCenter::start ()
+{
+    XCamReturn ret = XCAM_RETURN_NO_ERROR;
+
+    if (_image_processors.empty()) {
+        XCAM_LOG_ERROR ("process center start failed, no processor found");
+        return XCAM_RETURN_ERROR_PARAM;
+    }
+
+    for (ImageProcessorList::iterator i_pro = _image_processors.begin ();
+            i_pro != _image_processors.end(); ++i_pro)
+    {
+        SmartPtr<ImageProcessor> &processor = *i_pro;
+        XCAM_ASSERT (processor.ptr());
+        processor->set_callback (this);
+        ret = processor->start ();
+        if (ret != XCAM_RETURN_NO_ERROR) {
+            XCAM_LOG_ERROR ("processor(%s) start failed", XCAM_STR(processor->get_name()));
+            break;
+        }
+    }
+
+    if (ret != XCAM_RETURN_NO_ERROR)
+        stop();
+    else {
+        XCAM_LOG_INFO ("3a process center started");
+    }
+
+    return ret;
+}
+
+XCamReturn
+X3aImageProcessCenter::stop ()
+{
+    for (ImageProcessorList::iterator i_pro = _image_processors.begin ();
+            i_pro != _image_processors.end(); ++i_pro)
+    {
+        SmartPtr<ImageProcessor> &processor = *i_pro;
+        XCAM_ASSERT (processor.ptr());
+        processor->stop ();
+    }
+
+    XCAM_LOG_INFO ("3a process center stopped");
+
+    _image_processors.clear();
+    return XCAM_RETURN_NO_ERROR;
+}
+
+bool
+X3aImageProcessCenter::put_buffer (SmartPtr<VideoBuffer> &buf)
+{
+    XCAM_ASSERT (!_image_processors.empty());
+    if (_image_processors.empty())
+        return false;
+
+    ImageProcessorList::iterator i_pro = _image_processors.begin ();
+    SmartPtr<ImageProcessor> &processor = *i_pro;
+    if (processor->push_buffer (buf) != XCAM_RETURN_NO_ERROR)
+        return false;
+    return true;
+}
+
+
+XCamReturn
+X3aImageProcessCenter::put_3a_results (X3aResultList &results)
+{
+    XCamReturn ret = XCAM_RETURN_NO_ERROR;
+
+    XCAM_FAIL_RETURN (ERROR, !results.empty(), XCAM_RETURN_ERROR_PARAM, "results empty");
+
+    for (ImageProcessorIter i_pro = _image_processors.begin();
+            i_pro != _image_processors.end(); i_pro++) {
+        SmartPtr<ImageProcessor> &processor = *i_pro;
+        XCAM_ASSERT (processor.ptr());
+        ret = processor->push_3a_results (results);
+        if (ret != XCAM_RETURN_NO_ERROR && ret != XCAM_RETURN_BYPASS) {
+            XCAM_LOG_WARNING ("processor(%s) gailed on results", XCAM_STR(processor->get_name()));
+            break;
+        }
+        if (results.empty ()) {
+            XCAM_LOG_DEBUG ("results done");
+            return XCAM_RETURN_NO_ERROR;
+        }
+    }
+
+    if (!results.empty()) {
+        XCAM_LOG_DEBUG ("process center: results left without being processed");
+        return XCAM_RETURN_BYPASS;
+    }
+
+    return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+X3aImageProcessCenter::put_3a_result (SmartPtr<X3aResult> &result)
+{
+    XCamReturn ret = XCAM_RETURN_NO_ERROR;
+
+    XCAM_FAIL_RETURN (ERROR, !result.ptr(), XCAM_RETURN_ERROR_PARAM, "result empty");
+
+    for (ImageProcessorIter i_pro = _image_processors.begin();
+            i_pro != _image_processors.end(); i_pro++)
+    {
+        SmartPtr<ImageProcessor> &processor = *i_pro;
+        XCAM_ASSERT (processor.ptr());
+        ret = processor->push_3a_result (result);
+
+        if (ret == XCAM_RETURN_BYPASS)
+            continue;
+
+        if (ret == XCAM_RETURN_NO_ERROR)
+            return XCAM_RETURN_NO_ERROR;
+
+        XCAM_LOG_WARNING ("processor(%s) failed on result", XCAM_STR(processor->get_name()));
+        return ret;
+    }
+
+    if (ret == XCAM_RETURN_BYPASS) {
+        XCAM_LOG_WARNING ("processor center: no processor can handle result()");
+    }
+
+    return ret;
+}
+
+void
+X3aImageProcessCenter::process_buffer_done (ImageProcessor *processor, SmartPtr<VideoBuffer> &buf)
+{
+    ImageProcessorIter i_pro = _image_processors.begin();
+    for (; i_pro != _image_processors.end(); ++i_pro)
+    {
+        SmartPtr<ImageProcessor> &cur_pro = *i_pro;
+        XCAM_ASSERT (cur_pro.ptr());
+        if (cur_pro.ptr() == processor)
+            break;
+    }
+
+    XCAM_ASSERT (i_pro != _image_processors.end());
+    if (i_pro == _image_processors.end()) {
+        XCAM_LOG_ERROR ("processor doesn't found from list of image center");
+        return;
+    }
+
+    if (++i_pro != _image_processors.end()) {
+        SmartPtr<ImageProcessor> &next_processor = *i_pro;
+        XCAM_ASSERT (next_processor.ptr());
+        XCamReturn ret = next_processor->push_buffer (buf);
+        if (ret != XCAM_RETURN_NO_ERROR) {
+            XCAM_LOG_ERROR ("processor(%s) failed in push_buffer", next_processor->get_name());
+        }
+        return;
+    }
+
+    //all processor done
+    if (_callback)
+        _callback->process_buffer_done (processor, buf);
+    else
+        ImageProcessCallback::process_buffer_done (processor, buf);
+}
+
+void
+X3aImageProcessCenter::process_buffer_failed (ImageProcessor *processor, SmartPtr<VideoBuffer> &buf)
+{
+    if (_callback)
+        _callback->process_buffer_failed(processor, buf);
+    else
+        ImageProcessCallback::process_buffer_failed (processor, buf);
+}
+
+void
+X3aImageProcessCenter::process_image_result_done (ImageProcessor *processor, SmartPtr<X3aResult> &result)
+{
+    if (_callback)
+        _callback->process_image_result_done(processor, result);
+    else
+        ImageProcessCallback::process_image_result_done (processor, result);
+}
+
+};
diff --git a/xcore/x3a_image_process_center.h b/xcore/x3a_image_process_center.h
new file mode 100644
index 0000000..7e4516f
--- /dev/null
+++ b/xcore/x3a_image_process_center.h
@@ -0,0 +1,66 @@
+/*
+ * x3a_image_process_center.h - 3a process center
+ *
+ *  Copyright (c) 2014-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: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#ifndef XCAM_3A_IMAGE_PROCESS_CENTER_H
+#define XCAM_3A_IMAGE_PROCESS_CENTER_H
+
+#include "xcam_common.h"
+#include "xcam_defs.h"
+#include "xcam_utils.h"
+#include "image_processor.h"
+
+namespace XCam {
+
+class X3aImageProcessCenter
+    : public ImageProcessCallback
+{
+    typedef std::list<SmartPtr<ImageProcessor> > ImageProcessorList;
+    typedef std::list<SmartPtr<ImageProcessor> >::iterator ImageProcessorIter;
+public:
+    explicit X3aImageProcessCenter();
+    ~X3aImageProcessCenter();
+
+    bool insert_processor (SmartPtr<ImageProcessor> &processor);
+    bool has_processors ();
+    bool set_image_callback (ImageProcessCallback *callback);
+
+    XCamReturn start ();
+    XCamReturn stop ();
+
+    bool put_buffer (SmartPtr<VideoBuffer> &buf);
+
+    XCamReturn put_3a_results (X3aResultList &results);
+    XCamReturn put_3a_result (SmartPtr<X3aResult> &result);
+
+    //derived from ImageProcessCallback
+    virtual void process_buffer_done (ImageProcessor *processor, SmartPtr<VideoBuffer> &buf);
+    virtual void process_buffer_failed (ImageProcessor *processor, SmartPtr<VideoBuffer> &buf);
+    virtual void process_image_result_done (ImageProcessor *processor, SmartPtr<X3aResult> &result);
+
+private:
+    XCAM_DEAD_COPY (X3aImageProcessCenter);
+
+private:
+    ImageProcessorList             _image_processors;
+    ImageProcessCallback          *_callback;
+};
+
+};
+#endif //XCAM_3A_IMAGE_PROCESS_CENTER_H
diff --git a/xcore/x3a_isp_config.cpp b/xcore/x3a_isp_config.cpp
new file mode 100644
index 0000000..224d836
--- /dev/null
+++ b/xcore/x3a_isp_config.cpp
@@ -0,0 +1,283 @@
+/*
+ * x3a_isp_config.h - 3A ISP config
+ *
+ *  Copyright (c) 2014-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: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#include "x3a_isp_config.h"
+#include "isp_config_translator.h"
+
+namespace XCam {
+
+void AtomIspConfigContent::clear ()
+{
+    xcam_mem_clear (this);
+}
+
+void
+AtomIspConfigContent::copy (const struct atomisp_parameters &config)
+{
+    xcam_mem_clear (&isp_config);
+    if (config.wb_config) {
+        wb = *config.wb_config;
+        isp_config.wb_config = &wb;
+    }
+    if (config.cc_config) {
+        cc = *config.cc_config;
+        isp_config.cc_config = &cc;
+    }
+    if (config.tnr_config) {
+        tnr = *config.tnr_config;
+        isp_config.tnr_config = &tnr;
+    }
+    if (config.ecd_config) {
+        ecd_config = *config.ecd_config;
+        isp_config.ecd_config = &ecd_config;
+    }
+    if (config.ynr_config) {
+        ynr = *config.ynr_config;
+        isp_config.ynr_config = &ynr;
+    }
+    if (config.fc_config) {
+        fc_config = *config.fc_config;
+        isp_config.fc_config = &fc_config;
+    }
+    if (config.cnr_config) {
+        cnr = *config.cnr_config;
+        isp_config.cnr_config = &cnr;
+    }
+    if (config.macc_config) {
+        macc_config = *config.macc_config;
+        isp_config.macc_config = &macc_config;
+    }
+    if (config.ctc_config) {
+        ctc_config = *config.ctc_config;
+        isp_config.ctc_config = &ctc_config;
+    }
+    if (config.formats_config) {
+        formats = *config.formats_config;
+        isp_config.formats_config = &formats;
+    }
+    if (config.aa_config) {
+        aa = *config.aa_config;
+        isp_config.aa_config = &aa;
+    }
+    if (config.baa_config) {
+        baa = *config.baa_config;
+        isp_config.baa_config = &baa;
+    }
+    if (config.ce_config) {
+        ce = *config.ce_config;
+        isp_config.ce_config = &ce;
+    }
+    if (config.dvs_6axis_config) {
+        dvs_6axis = *config.dvs_6axis_config;
+        isp_config.dvs_6axis_config = &dvs_6axis;
+    }
+    if (config.ob_config) {
+        ob = *config.ob_config;
+        isp_config.ob_config = &ob;
+    }
+    if (config.nr_config) {
+        nr = *config.nr_config;
+        isp_config.nr_config = &nr;
+    }
+    if (config.dp_config) {
+        dp = *config.dp_config;
+        isp_config.dp_config = &dp;
+    }
+    if (config.ee_config) {
+        ee = *config.ee_config;
+        isp_config.ee_config = &ee;
+    }
+    if (config.de_config) {
+        de = *config.de_config;
+        isp_config.de_config = &de;
+    }
+    if (config.ctc_table) {
+        ctc_table = *config.ctc_table;
+        isp_config.ctc_table = &ctc_table;
+    }
+    if (config.gc_config) {
+        gc_config = *config.gc_config;
+        isp_config.gc_config = &gc_config;
+    }
+    if (config.anr_config) {
+        anr = *config.anr_config;
+        isp_config.anr_config = &anr;
+    }
+    if (config.a3a_config) {
+        a3a = *config.a3a_config;
+        isp_config.a3a_config = &a3a;
+    }
+    if (config.xnr_config) {
+        xnr = *config.xnr_config;
+        isp_config.xnr_config = &xnr;
+    }
+    if (config.dz_config) {
+        dz_config = *config.dz_config;
+        isp_config.dz_config = &dz_config;
+    }
+    if (config.yuv2rgb_cc_config) {
+        yuv2rgb_cc = *config.yuv2rgb_cc_config;
+        isp_config.yuv2rgb_cc_config = &yuv2rgb_cc;
+    }
+    if (config.rgb2yuv_cc_config) {
+        rgb2yuv_cc = *config.rgb2yuv_cc_config;
+        isp_config.rgb2yuv_cc_config = &rgb2yuv_cc;
+    }
+    if (config.macc_table) {
+        macc_table = *config.macc_table;
+        isp_config.macc_table = &macc_table;
+    }
+    if (config.gamma_table) {
+        gamma_table = *config.gamma_table;
+        isp_config.gamma_table = &gamma_table;
+    }
+    if (config.r_gamma_table) {
+        r_gamma_table = *config.r_gamma_table;
+        isp_config.r_gamma_table = &r_gamma_table;
+    }
+    if (config.g_gamma_table) {
+        g_gamma_table = *config.g_gamma_table;
+        isp_config.g_gamma_table = &g_gamma_table;
+    }
+    if (config.b_gamma_table) {
+        b_gamma_table = *config.b_gamma_table;
+        isp_config.b_gamma_table = &b_gamma_table;
+    }
+    if (config.shading_table) {
+        shading_table = *config.shading_table;
+        isp_config.shading_table = &shading_table;
+    }
+    if (config.morph_table) {
+        morph_table = *config.morph_table;
+        isp_config.morph_table = &morph_table;
+    }
+    if (config.xnr_table) {
+        xnr_table = *config.xnr_table;
+        isp_config.xnr_table = &xnr_table;
+    }
+    if (config.anr_thres) {
+        anr_thres = *config.anr_thres;
+        isp_config.anr_thres = &anr_thres;
+    }
+    if (config.motion_vector) {
+        motion_vector = *config.motion_vector;
+        isp_config.motion_vector = &motion_vector;
+    }
+}
+
+X3aIspConfig::X3aIspConfig ()
+{
+}
+
+X3aIspConfig::~X3aIspConfig()
+{
+    clear ();
+}
+
+
+bool X3aIspConfig::clear()
+{
+    _isp_content.clear ();
+    _3a_results.clear ();
+    return true;
+}
+
+bool
+X3aIspConfig::attach (SmartPtr<X3aResult> &result, IspConfigTranslator *translator)
+{
+    uint32_t type = result->get_type ();
+
+    XCAM_ASSERT (translator);
+
+    if (!result.ptr() || !result->get_ptr ()) {
+        XCAM_LOG_ERROR ("3A result empty");
+        return false;
+    }
+    switch (type) {
+    case X3aIspConfig::IspAllParameters: {
+        X3aAtomIspParametersResult *isp_3a =
+            dynamic_cast<X3aAtomIspParametersResult*>(result.ptr());
+        XCAM_ASSERT (isp_3a);
+        _isp_content.copy (isp_3a->get_isp_config());
+    }
+    break;
+
+    case XCAM_3A_RESULT_WHITE_BALANCE: {
+        struct atomisp_wb_config wb;
+        X3aWhiteBalanceResult *wb_res =
+            dynamic_cast<X3aWhiteBalanceResult*>(result.ptr());
+        XCAM_ASSERT (wb_res);
+        xcam_mem_clear (&wb);
+        if (translator->translate_white_balance (wb_res->get_standard_result(), wb)
+                != XCAM_RETURN_NO_ERROR) {
+            XCAM_LOG_WARNING ("translate white balance failed");
+            return false;
+        }
+        _isp_content.wb = wb;
+        _isp_content.isp_config.wb_config = &_isp_content.wb;
+    }
+    break;
+    case XCAM_3A_RESULT_BLACK_LEVEL: {
+        struct atomisp_ob_config ob;
+        X3aBlackLevelResult *bl_res =
+            dynamic_cast<X3aBlackLevelResult*>(result.ptr());
+        XCAM_ASSERT (bl_res);
+        xcam_mem_clear (&ob);
+        if (translator->translate_black_level (bl_res->get_standard_result(), ob)
+                != XCAM_RETURN_NO_ERROR) {
+            XCAM_LOG_WARNING ("translate black level failed");
+            return false;
+        }
+        _isp_content.ob = ob;
+        _isp_content.isp_config.ob_config = &_isp_content.ob;
+    }
+    break;
+    case XCAM_3A_RESULT_YUV2RGB_MATRIX:
+    case XCAM_3A_RESULT_RGB2YUV_MATRIX:
+    {
+        struct atomisp_cc_config cc;
+        X3aColorMatrixResult *cc_res =
+            dynamic_cast<X3aColorMatrixResult*>(result.ptr());
+        XCAM_ASSERT (cc_res);
+        xcam_mem_clear (&cc);
+        if (translator->translate_color_matrix (cc_res->get_standard_result(), cc)
+                != XCAM_RETURN_NO_ERROR) {
+            XCAM_LOG_WARNING ("translate color matrix failed");
+            return false;
+        }
+        if (type == XCAM_3A_RESULT_YUV2RGB_MATRIX) {
+            _isp_content.yuv2rgb_cc = cc;
+            _isp_content.isp_config.yuv2rgb_cc_config = &_isp_content.yuv2rgb_cc;
+        } else {
+            _isp_content.rgb2yuv_cc = cc;
+            _isp_content.isp_config.rgb2yuv_cc_config = &_isp_content.rgb2yuv_cc;
+        }
+    }
+    break;
+    default:
+        return false;
+    }
+
+    _3a_results.push_back (result);
+    return true;
+}
+
+};
+
diff --git a/xcore/x3a_isp_config.h b/xcore/x3a_isp_config.h
new file mode 100644
index 0000000..f54072b
--- /dev/null
+++ b/xcore/x3a_isp_config.h
@@ -0,0 +1,191 @@
+/*
+ * x3a_isp_config.h - 3A ISP config
+ *
+ *  Copyright (c) 2014-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: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#ifndef XCAM_3A_ISP_CONFIG_H
+#define XCAM_3A_ISP_CONFIG_H
+
+#include "xcam_defs.h"
+#include "xcam_common.h"
+#include "xcam_utils.h"
+#include "xcam_3a_result.h"
+#include "x3a_result.h"
+#include <linux/atomisp.h>
+
+namespace XCam {
+
+#define XCAM_3A_ISP_RESULT_TYPE_START (XCAM_3A_RESULT_USER_DEFINED_TYPE + 0x1000)
+
+struct AtomIspConfigContent {
+    struct atomisp_parameters   isp_config;
+    //content
+    struct atomisp_wb_config     wb;
+    struct atomisp_ob_config     ob; //black level
+    struct atomisp_cc_config     cc;
+    struct atomisp_cc_config     yuv2rgb_cc;
+    struct atomisp_cc_config     rgb2yuv_cc;
+    struct atomisp_nr_config     nr;
+    struct atomisp_tnr_config    tnr;
+    struct atomisp_ynr_config    ynr;
+    struct atomisp_cnr_config    cnr;
+    struct atomisp_anr_config    anr;
+    struct atomisp_xnr_config    xnr;
+    struct atomisp_xnr_table     xnr_table;
+    struct atomisp_ee_config     ee;
+    struct atomisp_dp_config     dp;
+    struct atomisp_de_config     de;
+    struct atomisp_ecd_config    ecd_config;
+    struct atomisp_fc_config     fc_config;
+    struct atomisp_ctc_config    ctc_config;
+    struct atomisp_ctc_table     ctc_table;
+    struct atomisp_macc_config   macc_config;
+    struct atomisp_macc_table    macc_table;
+    struct atomisp_gamma_table   gamma_table;
+    struct atomisp_rgb_gamma_table r_gamma_table;
+    struct atomisp_rgb_gamma_table g_gamma_table;
+    struct atomisp_rgb_gamma_table b_gamma_table;
+    struct atomisp_gc_config     gc_config;
+    struct atomisp_shading_table shading_table;
+    struct atomisp_3a_config     a3a;
+
+    struct atomisp_dvs_6axis_config dvs_6axis;
+
+
+    struct atomisp_formats_config formats;
+    struct atomisp_aa_config     aa;
+    struct atomisp_aa_config     baa;
+    struct atomisp_ce_config     ce;
+    struct atomisp_morph_table   morph_table;
+    struct atomisp_anr_thres     anr_thres;
+
+    struct atomisp_dz_config     dz_config;
+    struct atomisp_vector        motion_vector;
+
+    void clear ();
+    void copy (const struct atomisp_parameters &config);
+
+    AtomIspConfigContent () {
+        clear ();
+    }
+};
+
+class IspConfigTranslator;
+
+class X3aIspConfig
+{
+public:
+    enum X3aIspConfigType {
+        IspAllParameters = XCAM_3A_ISP_RESULT_TYPE_START,
+        IspExposureParameters,
+    };
+
+    struct X3aIspResultDummy {
+        XCam3aResultHead head;
+    };
+public:
+    explicit X3aIspConfig ();
+    virtual ~X3aIspConfig();
+
+public:
+    const struct atomisp_parameters &get_isp_configs () const {
+        return _isp_content.isp_config;
+    }
+    struct atomisp_parameters &get_isp_configs () {
+        return _isp_content.isp_config;
+    }
+    bool clear ();
+    bool attach (SmartPtr<X3aResult> &result, IspConfigTranslator *translator);
+
+private:
+    XCAM_DEAD_COPY (X3aIspConfig);
+
+protected:
+    AtomIspConfigContent             _isp_content;
+    std::list< SmartPtr<X3aResult> > _3a_results;
+};
+
+template <typename IspConfig, typename StandardResult, uint32_t type>
+class X3aIspResultT
+    : public X3aStandardResultT<StandardResult>
+{
+public:
+    X3aIspResultT (
+        XCamImageProcessType process_type = XCAM_IMAGE_PROCESS_ALWAYS
+    )
+        : X3aStandardResultT<StandardResult> (type, process_type)
+    {
+        X3aResult::set_ptr((void*)&_isp_config);
+    }
+
+    ~X3aIspResultT () {}
+
+    // set config
+    void set_isp_config (IspConfig &config) {
+        _isp_config = config;
+    }
+    const IspConfig &get_isp_config () const {
+        return _isp_config;
+    }
+
+private:
+    IspConfig _isp_config;
+};
+
+
+/* special X3aAtomIspParametersResult type */
+template <>
+class X3aIspResultT<struct atomisp_parameters, X3aIspConfig::X3aIspResultDummy, X3aIspConfig::IspAllParameters>
+            : public X3aStandardResultT<X3aIspConfig::X3aIspResultDummy>
+    {
+public:
+        X3aIspResultT (
+            XCamImageProcessType process_type = XCAM_IMAGE_PROCESS_ALWAYS)
+            : X3aStandardResultT<X3aIspConfig::X3aIspResultDummy> ((uint32_t)X3aIspConfig::IspAllParameters, process_type)
+        {
+            X3aResult::set_ptr((void*)&_content.isp_config);
+        }
+
+        ~X3aIspResultT () {}
+
+        // get config
+        struct atomisp_parameters &get_isp_config () {
+            return _content.isp_config;
+        }
+        const struct atomisp_parameters &get_isp_config () const {
+            return _content.isp_config;
+        }
+
+        // set config
+        void set_isp_config (struct atomisp_parameters &config) {
+            _content.copy (config);
+        }
+
+private:
+        AtomIspConfigContent      _content;
+    };
+
+typedef
+X3aIspResultT<struct atomisp_parameters, X3aIspConfig::X3aIspResultDummy, X3aIspConfig::IspAllParameters> X3aAtomIspParametersResult;
+typedef
+X3aIspResultT<struct atomisp_exposure, XCam3aResultExposure, X3aIspConfig::IspExposureParameters> X3aIspExposureResult;
+
+};
+
+#endif //XCAM_3A_ISP_CONFIG_H
+
diff --git a/xcore/x3a_result.cpp b/xcore/x3a_result.cpp
new file mode 100644
index 0000000..bea897f
--- /dev/null
+++ b/xcore/x3a_result.cpp
@@ -0,0 +1,25 @@
+/*
+ * x3a_result.cpp - 3A calculation result
+ *
+ *  Copyright (c) 2014 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: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#include "x3a_result.h"
+
+namespace XCam {
+
+};
diff --git a/xcore/x3a_result.h b/xcore/x3a_result.h
new file mode 100644
index 0000000..5ac5bc6
--- /dev/null
+++ b/xcore/x3a_result.h
@@ -0,0 +1,144 @@
+/*
+ * x3a_result.h - 3A calculation result
+ *
+ *  Copyright (c) 2014-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: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#ifndef XCAM_3A_RESULT_H
+#define XCAM_3A_RESULT_H
+
+#include "xcam_common.h"
+#include "xcam_utils.h"
+#include "smartptr.h"
+#include "xcam_3a_result.h"
+#include <list>
+
+namespace XCam {
+
+class X3aResult
+{
+protected:
+    explicit X3aResult (
+        uint32_t type,
+        XCamImageProcessType process_type = XCAM_IMAGE_PROCESS_ALWAYS,
+        uint64_t timestamp = XCam::InvalidTimestamp
+    )
+        : _type (type)
+        , _process_type (process_type)
+        , _timestamp (timestamp)
+        , _ptr (NULL)
+        , _processed (false)
+    {}
+
+public:
+    virtual ~X3aResult() {}
+
+    void *get_ptr () const {
+        return _ptr;
+    }
+    bool is_done() const {
+        return _processed;
+    }
+    void set_done (bool flag) {
+        _processed = flag;
+    }
+    uint64_t get_timestamp () const {
+        return _timestamp;
+    }
+    uint32_t get_type () const {
+        return _type;
+    }
+
+    void set_process_type (XCamImageProcessType process) {
+        _process_type = process;
+    }
+    XCamImageProcessType get_process_type () const {
+        return _process_type;
+    }
+
+protected:
+    void set_ptr (void *ptr) {
+        _ptr = ptr;
+    }
+
+    //virtual bool to_isp_config (SmartPtr<X3aIspConfig>  &config) = 0;
+
+private:
+    XCAM_DEAD_COPY (X3aResult);
+
+protected:
+    //XCam3aResultType      _type;
+    uint32_t              _type;  // XCam3aResultType
+    XCamImageProcessType  _process_type;
+    uint64_t              _timestamp;
+    void                 *_ptr;
+    bool                  _processed;
+};
+
+typedef std::list<SmartPtr<X3aResult>>  X3aResultList;
+
+/* !
+ * \template StandardResult must inherited from XCam3aResultHead
+ */
+template <typename StandardResult>
+class X3aStandardResultT
+    : public X3aResult
+{
+public:
+    explicit X3aStandardResultT (uint32_t type, XCamImageProcessType process_type = XCAM_IMAGE_PROCESS_ALWAYS)
+        : X3aResult (type, process_type)
+    {
+        set_ptr((void*)&_result);
+        _result.head.type = (XCam3aResultType)type;
+        _result.head.process_type = _process_type;
+        _result.head.version = XCAM_VERSION;
+    }
+    ~X3aStandardResultT () {}
+
+    void set_standard_result (StandardResult &res) {
+        uint32_t offset = sizeof (XCam3aResultHead);
+        XCAM_ASSERT (sizeof (StandardResult) >= offset);
+        memcpy ((uint8_t*)(&_result) + offset, (uint8_t*)(&res) + offset, sizeof (StandardResult) - offset);
+    }
+
+    StandardResult &get_standard_result () {
+        return _result;
+    }
+    const StandardResult &get_standard_result () const {
+        return _result;
+    }
+
+private:
+    StandardResult _result;
+};
+
+typedef X3aStandardResultT<XCam3aResultWhiteBalance>   X3aWhiteBalanceResult;
+typedef X3aStandardResultT<XCam3aResultBlackLevel>     X3aBlackLevelResult;
+typedef X3aStandardResultT<XCam3aResultColorMatrix>    X3aColorMatrixResult;
+typedef X3aStandardResultT<XCam3aResultExposure>       X3aExposureResult;
+typedef X3aStandardResultT<XCam3aResultFocus>          X3aFocusResult;
+typedef X3aStandardResultT<XCam3aResultDemosaic>       X3aDemosaicResult;
+typedef X3aStandardResultT<XCam3aResultDefectPixel>    X3aDefectPixelResult;
+typedef X3aStandardResultT<XCam3aResultNoiseReduction> X3aNoiseReductionResult;
+typedef X3aStandardResultT<XCam3aResultEdgeEnhancement>  X3aEdgeEnhancementResult;
+typedef X3aStandardResultT<XCam3aResultGammaTable>     X3aGammaTableResult;
+typedef X3aStandardResultT<XCam3aResultMaccMatrix>     X3aMaccMatrixResult;
+typedef X3aStandardResultT<XCam3aResultChromaToneControl> X3aChromaToneControlResult;
+
+};
+
+#endif //XCAM_3A_RESULT_H
diff --git a/xcore/x3a_statistics_queue.cpp b/xcore/x3a_statistics_queue.cpp
new file mode 100644
index 0000000..11c048c
--- /dev/null
+++ b/xcore/x3a_statistics_queue.cpp
@@ -0,0 +1,125 @@
+/*
+ * x3a_statistics_queue.c - statistics queue
+ *
+ *  Copyright (c) 2014-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: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#include "x3a_statistics_queue.h"
+#include <linux/videodev2.h>
+#include <linux/atomisp.h>
+
+namespace XCam {
+
+X3aIspStatistics::~X3aIspStatistics ()
+{
+    if (_3a_pool && _3a_stats)
+        _3a_pool->release_stats(_3a_stats);
+}
+
+X3aStatisticsQueue::X3aStatisticsQueue()
+    : _list_size(6)
+    , _list_allocated(false)
+{
+    xcam_mem_clear (&_grid_info);
+}
+
+X3aStatisticsQueue::~X3aStatisticsQueue()
+{
+    clear ();
+}
+
+bool
+X3aStatisticsQueue::pre_alloc_stats ()
+{
+    XCAM_ASSERT (_grid_info.width && _grid_info.height);
+    XCAM_ASSERT (_grid_info.aligned_width && _grid_info.aligned_height);
+    XCAM_ASSERT (_list_size);
+    XCAM_ASSERT (_3a_stats_list.empty());
+
+    uint32_t grid_size = _grid_info.aligned_width * _grid_info.aligned_height;
+    //uint32_t grid_size = _grid_info.width * _grid_info.height;
+
+    for (uint32_t i = 0; i < _list_size; ++i) {
+        struct atomisp_3a_statistics *stats = xcam_malloc0_type (struct atomisp_3a_statistics);
+        stats->data = (struct atomisp_3a_output*)xcam_malloc0 (grid_size * sizeof(*stats->data));
+        XCAM_ASSERT (stats && stats->data);
+        if (!stats || !stats->data)
+            return false;
+        stats->grid_info = _grid_info;
+        _3a_stats_list.push (stats);
+    }
+
+    _list_allocated = true;
+    return true;
+}
+
+SmartPtr<X3aIspStatistics>
+X3aStatisticsQueue::acquire_stats ()
+{
+    struct atomisp_3a_statistics *stats;
+
+    SmartLock locker(_list_mutex);
+
+    if (!_list_allocated && !pre_alloc_stats ()) {
+        XCAM_LOG_ERROR ("prealloc 3a stats failed");
+        return NULL;
+    }
+
+    if (_3a_stats_list.empty())
+        _list_release.wait (_list_mutex);
+
+    if (_3a_stats_list.empty()) {
+        XCAM_LOG_WARNING ("3a stats list waked up but still empty, check why");
+        return NULL;
+    }
+
+    stats = _3a_stats_list.front();
+    XCAM_ASSERT (stats);
+    _3a_stats_list.pop ();
+    return new X3aIspStatistics(this, stats);
+
+}
+
+void
+X3aStatisticsQueue::wakeup ()
+{
+    XCAM_LOG_INFO ("wakeup all stats in acquiring");
+    _list_release.broadcast ();
+}
+
+void
+X3aStatisticsQueue::release_stats (struct atomisp_3a_statistics *_3a_stats)
+{
+    SmartLock locker(_list_mutex);
+    _3a_stats_list.push (_3a_stats);
+    XCAM_ASSERT (_3a_stats_list.size() <= _list_size);
+    _list_release.signal ();
+}
+
+void
+X3aStatisticsQueue::clear ()
+{
+    XCAM_ASSERT (!_list_allocated || _3a_stats_list.size() == _list_size);
+    while (!_3a_stats_list.empty()) {
+        struct atomisp_3a_statistics *stats = _3a_stats_list.front ();
+        _3a_stats_list.pop ();
+        xcam_free (stats->data);
+        xcam_free (stats);
+    }
+}
+
+};
diff --git a/xcore/x3a_statistics_queue.h b/xcore/x3a_statistics_queue.h
new file mode 100644
index 0000000..b337702
--- /dev/null
+++ b/xcore/x3a_statistics_queue.h
@@ -0,0 +1,108 @@
+/*
+ * x3a_statistics_queue.h - statistics queue
+ *
+ *  Copyright (c) 2014-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: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#ifndef XCAM_3A_STATISTIC_QUEUE_H
+#define XCAM_3A_STATISTIC_QUEUE_H
+
+#include "xcam_common.h"
+#include "x3a_event.h"
+#include "xcam_mutex.h"
+#include "xcam_utils.h"
+#include "smartptr.h"
+#include <queue>
+#include <linux/atomisp.h>
+
+namespace XCam {
+
+class X3aStatisticsQueue;
+
+class X3aIspStatistics
+    : public X3aEvent
+{
+    friend class X3aStatisticsQueue;
+protected:
+    explicit X3aIspStatistics (
+        X3aStatisticsQueue* pool,
+        struct atomisp_3a_statistics *stats,
+        uint64_t timestamp =  XCam::InvalidTimestamp
+    )
+        : X3aEvent (X3aEvent::TYPE_ISP_STATISTICS, timestamp)
+        , _3a_pool (pool)
+        , _3a_stats (stats)
+        , _timestamp (timestamp)
+    {}
+public:
+    virtual ~X3aIspStatistics ();
+    const struct atomisp_3a_statistics *get_3a_stats () const {
+        return _3a_stats;
+    }
+    struct atomisp_3a_statistics *get_3a_stats () {
+        return _3a_stats;
+    }
+
+    int64_t get_timestamp () const {
+        return _timestamp;
+    }
+    void set_timestamp (int64_t timestamp) {
+        _timestamp = timestamp;
+    }
+
+private:
+    XCAM_DEAD_COPY (X3aIspStatistics);
+
+private:
+    X3aStatisticsQueue           *_3a_pool;
+    struct atomisp_3a_statistics *_3a_stats;
+    int64_t                       _timestamp;
+};
+
+class X3aStatisticsQueue {
+    friend class X3aIspStatistics;
+    typedef std::queue<struct atomisp_3a_statistics *> StatsList;
+public:
+    explicit X3aStatisticsQueue ();
+    ~X3aStatisticsQueue();
+
+    void set_grid_info (struct atomisp_grid_info &info) {
+        _grid_info = info;
+    }
+
+    SmartPtr<X3aIspStatistics> acquire_stats ();
+    void wakeup ();
+
+private:
+    void release_stats (struct atomisp_3a_statistics *_3a_stats);
+    bool pre_alloc_stats ();
+    void clear ();
+
+    XCAM_DEAD_COPY (X3aStatisticsQueue);
+
+private:
+    StatsList   _3a_stats_list;
+    uint32_t    _list_size;
+    bool        _list_allocated;
+    XCam::Mutex _list_mutex;
+    XCam::Cond  _list_release;
+    struct atomisp_grid_info  _grid_info;
+};
+
+};
+
+#endif //XCAM_3A_STATISTIC_QUEUE_H
diff --git a/xcore/xcam_3a_result.h b/xcore/xcam_3a_result.h
new file mode 100644
index 0000000..1038522
--- /dev/null
+++ b/xcore/xcam_3a_result.h
@@ -0,0 +1,196 @@
+/*
+ * xcam_3a_result.h - 3A result interface
+ *
+ *  Copyright (c) 2014-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: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#ifndef C_XCAM_3A_RESULT_H
+#define C_XCAM_3A_RESULT_H
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <stddef.h>
+
+XCAM_BEGIN_DECLARE
+
+typedef enum _ImageProcessType {
+    XCAM_IMAGE_PROCESS_ONCE,
+    XCAM_IMAGE_PROCESS_ALWAYS,
+} XCamImageProcessType;
+
+typedef enum _XCam3aResultType {
+    /* White Balance */
+    XCAM_3A_RESULT_WHITE_BALANCE,
+    XCAM_3A_RESULT_BLACK_LEVEL,
+    XCAM_3A_RESULT_YUV2RGB_MATRIX,
+    XCAM_3A_RESULT_RGB2YUV_MATRIX,
+
+    /* Exposure */
+    XCAM_3A_RESULT_EXPOSURE,
+
+    /* Focus */
+    XCAM_3A_RESULT_FOCUS,
+
+    XCAM_3A_RESULT_DEMOSAIC,
+    //XCAM_3A_RESULT_EIGEN_COLOR_DEMOSAICING,
+    XCAM_3A_RESULT_DEFECT_PIXEL_CORRECTION,
+
+    /* noise reduction */
+    XCAM_3A_RESULT_NOISE_REDUCTION,
+    XCAM_3A_RESULT_TEMPORAL_NOISE_REDUCTION,
+    XCAM_3A_RESULT_LUMA_NOISE_REDUCTION,
+    XCAM_3A_RESULT_ADVANCED_NOISE_REDUCTION,
+    XCAM_3A_RESULT_CHROMA_NOISER_EDUCTION,
+
+    XCAM_3A_RESULT_EDGE_ENHANCEMENT,
+    //XCAM_3A_RESULT_FRIGLE_CONTROL,
+    XCAM_3A_RESULT_MACC,
+    //XCAM_3A_RESULT_MACCTABLE,
+    XCAM_3A_RESULT_CHROMA_TONE_CONTROL,
+    //XCAM_3A_RESULT_CHROMATONECONTROLTABLE,
+    XCAM_3A_RESULT_CHROMA_ENHANCEMENT,
+    XCAM_3A_RESULT_Y_GAMMA,
+    XCAM_3A_RESULT_R_GAMMA,
+    XCAM_3A_RESULT_G_GAMMA,
+    XCAM_3A_RESULT_B_GAMMA,
+    //XCAM_3A_RESULT_SHADING_TABLE,
+    XCAM_3A_RESULT_USER_DEFINED_TYPE = 0x8000,
+} XCam3aResultType;
+
+/* matrix size 3x3 */
+#define XCAM_COLOR_MATRIX_SIZE 9
+#define XCAM_GAMMA_TABLE_SIZE 256
+#define XCAM_CHROMA_AXIS_SIZE 16
+#define XCAM_CHROMA_MATRIX_SIZE 4
+
+typedef struct _XCam3aResultHead {
+    XCam3aResultType      type;
+    XCamImageProcessType  process_type;
+    uint32_t              version;
+    void                  (*destroy) (void);
+} XCam3aResultHead;
+
+typedef struct _XCam3aResultList {
+    XCam3aResultHead *result;
+    XCam3aResultHead *next;
+} XCam3aResultList;
+
+typedef struct _XCam3aResultWhiteBalance {
+    XCam3aResultHead head;
+
+    /* data */
+    double           r_gain;
+    double           gr_gain;
+    double           gb_gain;
+    double           b_gain;
+} XCam3aResultWhiteBalance;
+
+typedef struct _XCam3aResultBlackLevel {
+    XCam3aResultHead head;
+
+    /* data */
+    double           r_level;
+    double           gr_level;
+    double           gb_level;
+    double           b_level;
+} XCam3aResultBlackLevel;
+
+typedef struct _XCam3aResultColorMatrix {
+    XCam3aResultHead head;
+
+    /* data */
+    double           matrix [XCAM_COLOR_MATRIX_SIZE];
+} XCam3aResultColorMatrix;
+
+typedef struct _XCam3aResultExposure {
+    XCam3aResultHead head;
+
+    /* data */
+    int32_t          exposure_time; //in micro seconds
+    double           analog_gain;   // multipler
+    double           digital_gain;  // multipler
+    double           aperture;      //fn
+} XCam3aResultExposure;
+
+typedef struct _XCam3aResultFocus {
+    XCam3aResultHead head;
+
+    /* data */
+    int32_t          position;
+} XCam3aResultFocus;
+
+typedef struct _XCam3aResultDemosaic {
+    XCam3aResultHead head;
+
+    /* data */
+    double           noise;
+    double           thresthold_cr;
+    double           thresthold_cb;
+} XCam3aResultDemosaic;
+
+
+/* DefectPixel Correction */
+typedef struct _XCam3aResultDefectPixel {
+    XCam3aResultHead head;
+
+    /* data */
+    double           gain;
+    double           thresthold;
+} XCam3aResultDefectPixel;
+
+typedef struct _XCam3aResultNoiseReduction {
+    XCam3aResultHead head;
+
+    /* data */
+    double           gain;
+    double           thresthold1;
+    double           thresthold2;
+} XCam3aResultNoiseReduction;
+
+typedef struct _XCam3aResultEdgeEnhancement {
+    XCam3aResultHead head;
+
+    /* data */
+    double           gain;
+    double           thresthold;
+} XCam3aResultEdgeEnhancement;
+
+typedef struct _XCam3aResultGammaTable {
+    XCam3aResultHead head;
+
+    /* data */
+    double           table[XCAM_GAMMA_TABLE_SIZE];
+} XCam3aResultGammaTable;
+
+typedef struct _XCam3aResultMaccMatrix {
+    XCam3aResultHead head;
+
+    /* data */
+    double           table[XCAM_CHROMA_AXIS_SIZE * XCAM_CHROMA_MATRIX_SIZE];
+} XCam3aResultMaccMatrix;
+
+typedef struct _XCam3aResultChromaToneControl {
+    XCam3aResultHead head;
+
+    /* data */
+    double           uv_gain [XCAM_GAMMA_TABLE_SIZE]; // according to Y
+} XCam3aResultChromaToneControl;
+
+
+XCAM_END_DECLARE
+
+#endif
diff --git a/xcore/xcam_3a_types.h b/xcore/xcam_3a_types.h
new file mode 100644
index 0000000..b9171dc
--- /dev/null
+++ b/xcore/xcam_3a_types.h
@@ -0,0 +1,132 @@
+/*
+ *  Copyright (c) 2014 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: Wind Yuan <feng.yuan@intel.com>
+ */
+
+/*!
+ * \file xcam_3a_types.h
+ * \brief 3A interface variable types
+ */
+
+#ifndef __XCAM_3A_TYPES_H
+#define __XCAM_3A_TYPES_H
+
+#include <string.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdint.h>
+
+typedef enum  {
+    XCAM_MODE_NONE = -1,
+    XCAM_MODE_PREVIEW = 0,
+    XCAM_MODE_CAPTURE = 1,
+    XCAM_MODE_VIDEO = 2,
+    XCAM_MODE_CONTINUOUS_CAPTURE = 3
+} XCamMode;
+
+typedef enum {
+    XCAM_AE_MODE_NOT_SET = -1,
+    XCAM_AE_MODE_AUTO,
+    XCAM_AE_MODE_MANUAL,
+    XCAM_AE_MODE_SHUTTER_PRIORITY,
+    XCAM_AE_MODE_APERTURE_PRIORITY
+} XCamAeMode;
+
+typedef enum {
+    XCAM_AE_METERING_MODE_AUTO,   /*mode_evaluative*/
+    XCAM_AE_METERING_MODE_SPOT,   /*window*/
+    XCAM_AE_METERING_MODE_CENTER,  /*mode_center*/
+} XCamAeMeteringMode;
+
+typedef enum {
+    XCAM_SCENE_MODE_NOT_SET = -1,
+    XCAM_SCENE_MODE_AUTO,
+    XCAM_SCENE_MODE_PORTRAIT,
+    XCAM_SCENE_MODE_SPORTS,
+    XCAM_SCENE_MODE_LANDSCAPE,
+    XCAM_SCENE_MODE_NIGHT,
+    XCAM_SCENE_MODE_NIGHT_PORTRAIT,
+    XCAM_SCENE_MODE_FIREWORKS,
+    XCAM_SCENE_MODE_TEXT,
+    XCAM_SCENE_MODE_SUNSET,
+    XCAM_SCENE_MODE_PARTY,
+    XCAM_SCENE_MODE_CANDLELIGHT,
+    XCAM_SCENE_MODE_BEACH_SNOW,
+    XCAM_SCENE_MODE_DAWN_DUSK,
+    XCAM_SCENE_MODE_FALL_COLORS,
+    XCAM_SCENE_MODE_BACKLIGHT
+} XCamSceneMode;
+
+typedef enum {
+    XCAM_AWB_MODE_NOT_SET = -1,
+    XCAM_AWB_MODE_AUTO = 0,
+    XCAM_AWB_MODE_MANUAL,
+    XCAM_AWB_MODE_DAYLIGHT,
+    XCAM_AWB_MODE_SUNSET,
+    XCAM_AWB_MODE_CLOUDY,
+    XCAM_AWB_MODE_TUNGSTEN,
+    XCAM_AWB_MODE_FLUORESCENT,
+    XCAM_AWB_MODE_WARM_FLUORESCENT,
+    XCAM_AWB_MODE_SHADOW,
+    XCAM_AWB_MODE_WARM_INCANDESCENT
+} XCamAwbMode;
+
+typedef enum {
+    XCAM_AE_ISO_MODE_AUTO,   /* Automatic */
+    XCAM_AE_ISO_MODE_MANUAL  /* Manual */
+} XCamIsoMode;
+
+typedef enum {
+    XCAM_AE_FLICKER_MODE_AUTO,
+    XCAM_AE_FLICKER_MODE_50HZ,
+    XCAM_AE_FLICKER_MODE_60HZ,
+    XCAM_AE_FLICKER_MODE_OFF
+} XCamFlickerMode;
+
+#if 0
+typedef enum {
+    XCAM_AF_MODE_NOT_SET = -1,
+    XCAM_AF_MODE_AUTO,
+    XCAM_AF_MODE_MACRO,
+    XCAM_AF_MODE_INFINITY,
+    XCAM_AF_MODE_FIXED,
+    XCAM_AF_MODE_MANUAL,
+    XCAM_AF_MODE_CONTINUOUS
+} XCamAfMode;
+#endif
+
+/*! \brief XCam3AWindow.  
+ * Represents a rectangle area. Could be converted to 
+ * AIQ ia_rectangle, see convert_xcam_to_ia_window().
+ */
+typedef struct _XCam3AWindow {
+	int32_t x_start; /*!< X of start point (left-upper corner) */
+	int32_t y_start; /*!< Y of start point (left-upper corner) */
+	int32_t x_end;   /*!< X of end point (right-bottom corner) */
+	int32_t y_end;   /*!< Y of start point (left-upper corner) */
+	int weight;
+} XCam3AWindow;
+
+typedef struct _XCamExposureResult {
+    int64_t time_in_us;
+    double analog_gain;
+    double digital_gain;
+    double aperture_fn;
+    int32_t iso;
+} XCamExposureResult;
+
+#endif //__XCAM_3A_TYPES_H
+
diff --git a/xcore/xcam_common.cpp b/xcore/xcam_common.cpp
new file mode 100644
index 0000000..6c7df2f
--- /dev/null
+++ b/xcore/xcam_common.cpp
@@ -0,0 +1,80 @@
+/*
+ * xcam_common.cpp - xcam common
+ *
+ *  Copyright (c) 2014-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: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#include "xcam_common.h"
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+
+void * xcam_malloc(size_t size)
+{
+    return malloc (size);
+}
+
+void * xcam_malloc0(size_t size)
+{
+    void * ptr = malloc (size);
+    memset (ptr, 0, size);
+    return ptr;
+}
+
+void xcam_free(void *ptr)
+{
+    if (ptr)
+        free (ptr);
+}
+
+int xcam_device_ioctl (int fd, int cmd, void *arg)
+{
+    int ret = 0;
+    int tried_time = 0;
+
+    if (fd < 0)
+        return -1;
+
+    while (1) {
+        ret = ioctl (fd, cmd, arg);
+        if (ret >= 0)
+            break;
+        if (errno != EINTR && errno != EAGAIN)
+            break;
+        if (++tried_time > 5)
+            break;
+    }
+
+    if (ret >= 0) {
+        XCAM_LOG_DEBUG ("ioctl return ok on fd(%d), cmd:%d", fd, cmd);
+    } else {
+        XCAM_LOG_DEBUG ("ioctl failed on fd(%d), cmd:%d, error:%s",
+                        fd, cmd, strerror(errno));
+    }
+    return ret;
+}
+
+const char *
+xcam_fourcc_to_string (uint32_t fourcc)
+{
+    static char str[5];
+
+    xcam_mem_clear (str);
+    memcpy (str, &fourcc, 4);
+    return str;
+}
+
diff --git a/xcore/xcam_common.h b/xcore/xcam_common.h
new file mode 100644
index 0000000..3efd320
--- /dev/null
+++ b/xcore/xcam_common.h
@@ -0,0 +1,77 @@
+/*
+ * xcam_common.h - xcam common and utilities
+ *
+ *  Copyright (c) 2014 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: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#ifndef XCAM_COMMON_H
+#define XCAM_COMMON_H
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <pthread.h>
+#include "xcam_defs.h"
+
+XCAM_BEGIN_DECLARE
+
+typedef enum {
+    XCAM_RETURN_NO_ERROR        = 0,
+    XCAM_RETURN_BYPASS          = 1,
+
+    /* errors */
+    XCAM_RETURN_ERROR_PARAM     = -1,
+    XCAM_RETURN_ERROR_MEM       = -2,
+    XCAM_RETURN_ERROR_FILE      = -3,
+    XCAM_RETURN_ERROR_AIQ       = -4,
+    XCAM_RETURN_ERROR_ISP       = -5,
+    XCAM_RETURN_ERROR_SENSOR    = -6,
+    XCAM_RETURN_ERROR_THREAD    = -7,
+    XCAM_RETURN_ERROR_IOCTL     = -8,
+
+    XCAM_RETURN_ERROR_TIMEOUT   = -9,
+
+    XCAM_RETURN_ERROR_UNKNOWN   = -255,
+} XCamReturn;
+
+#define xcam_malloc_type(TYPE) (TYPE*)(xcam_malloc(sizeof(TYPE)))
+#define xcam_malloc0_type(TYPE) (TYPE*)(xcam_malloc0(sizeof(TYPE)))
+#define xcam_mem_clear(ptr) memset((ptr), 0, sizeof(*(ptr)))
+
+void * xcam_malloc (size_t size);
+void * xcam_malloc0 (size_t size);
+
+void xcam_free (void *ptr);
+
+/*
+  * return, 0 successfully
+  *            else, check errno
+  */
+int xcam_device_ioctl (int fd, int cmd, void *arg);
+const char *xcam_fourcc_to_string (uint32_t fourcc);
+
+XCAM_END_DECLARE
+
+#endif //XCAM_COMMON_H
+
diff --git a/xcore/xcam_cpf_reader.c b/xcore/xcam_cpf_reader.c
new file mode 100644
index 0000000..c88dc6f
--- /dev/null
+++ b/xcore/xcam_cpf_reader.c
@@ -0,0 +1,165 @@
+/*
+ * xcam_thread.h - xcam basic thread
+ *
+ *  Copyright (c) 2014 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: Wind Yuan <feng.yuan@intel.com>
+ */
+
+
+#include "xcam_cpf_reader.h"
+#include "xcam_common.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include "libtbd.h"
+
+#undef XCAM_FAIL_RETURN_VAL
+#define XCAM_FAIL_RETURN_VAL(exp, ret) \
+    if (!(exp)) {                  \
+        XCAM_LOG_WARNING ("XCAM_FAIL_RETURN_VAL %s", #exp);  \
+        return ret;                \
+    }
+
+#undef XCAM_FAIL_RETURN
+#define XCAM_FAIL_RETURN(exp) \
+    if (!(exp)) {                  \
+        XCAM_LOG_WARNING ("XCAM_FAIL_RETURN %s", #exp);  \
+        return ;                \
+    }
+
+void *xcam_new0(size_t size)
+{
+    void *buf = malloc (size);
+    memset (buf, 0, size);
+    return buf;
+}
+
+XCamCpfBlob * xcam_cpf_blob_new ()
+{
+    return (XCamCpfBlob*) xcam_new0 (sizeof(XCamCpfBlob));
+}
+
+void xcam_cpf_blob_free (XCamCpfBlob *blob)
+{
+    XCAM_FAIL_RETURN (blob);
+
+    if (blob->data)
+        xcam_free (blob->data);
+
+    xcam_free (blob);
+}
+
+static int32_t
+read_cpf_file (const char *cpf_file, uint8_t **buf)
+{
+    int32_t size = 0;
+    FILE *fp = fopen (cpf_file, "rb");
+    XCAM_FAIL_RETURN_VAL (fp, -1);
+
+    *buf = NULL;
+
+    if (fseek (fp, 0, SEEK_END) < 0)
+        goto read_error;
+    if ((size = ftell (fp)) <= 0)
+        goto read_error;
+    if (fseek( fp, 0, SEEK_SET) < 0)
+        goto read_error;
+
+    *buf = (uint8_t*) xcam_new0 (size);
+    if (fread (*buf, 1, size, fp) != size)
+        goto read_error;
+
+    fclose (fp);
+    return size;
+
+read_error:
+    XCAM_LOG_ERROR ("read cpf(%s) failed", cpf_file);
+    fclose (fp);
+    if (*buf) {
+        xcam_free (*buf);
+        *buf = NULL;
+    }
+    return -1;
+
+}
+
+boolean
+xcam_cpf_read (const char *cpf_file, XCamCpfBlob *aiq_cpf, XCamCpfBlob *hal_cpf)
+{
+    uint8_t *cpf_buf;
+    int32_t cpf_size;
+
+    uint8_t *blob;
+    int32_t blob_size;
+
+    XCAM_FAIL_RETURN_VAL (cpf_file, FALSE);
+    XCAM_FAIL_RETURN_VAL (aiq_cpf, FALSE);
+
+    /* read cpf */
+    if ((cpf_size = read_cpf_file(cpf_file, &cpf_buf)) <= 0) {
+        XCAM_LOG_ERROR ("read cpf_file(%s) failed.", cpf_file);
+        return FALSE;
+    }
+
+    /* check sum */
+    if (tbd_validate (cpf_buf, cpf_size, tbd_tag_cpff) != tbd_err_none) {
+        XCAM_LOG_ERROR ("tbd validate cpf file(%s) failed.", cpf_file);
+        goto free_buf;
+    }
+
+    /* fetch AIQ */
+    if ( (tbd_get_record (cpf_buf, tbd_class_aiq, tbd_format_any,
+                          (void**)&blob, (size_t*)&blob_size) != tbd_err_none) ||
+            !blob || blob_size <= 0) {
+        XCAM_LOG_ERROR ("CPF parse AIQ record failed.");
+        goto free_buf;
+    }
+    aiq_cpf->data = (uint8_t*) malloc (blob_size);
+    aiq_cpf->size = blob_size;
+    memcpy (aiq_cpf->data, blob, blob_size);
+
+
+#if 0 //DRV not necessary
+    /* fetch DRV */
+    if (tbd_get_record (cpf_buf, tbd_class_drv, tbd_format_any,
+                        &drv_blob.data, &drv_blob.size) != tbd_err_none) {
+        XCAM_LOG_ERROR ("CPF parse DRV record failed.");
+        return FALSE;
+    }
+#endif
+
+
+    /* fetch HAL */
+    if (hal_cpf) {
+        if (tbd_get_record (cpf_buf, tbd_class_hal, tbd_format_any,
+                            (void**)&blob, (size_t*)&blob_size) != tbd_err_none) {
+            XCAM_LOG_WARNING ("CPF doesn't have HAL record.");
+            // ignore HAL, not necessary
+        } else if (blob && blob_size > 0) {
+            hal_cpf->data = (uint8_t*) malloc (blob_size);
+            hal_cpf->size = blob_size;
+            memcpy (hal_cpf->data, blob, blob_size);
+        }
+    }
+
+    xcam_free (cpf_buf);
+    return TRUE;
+
+free_buf:
+    xcam_free (cpf_buf);
+    return FALSE;
+
+}
diff --git a/xcore/xcam_cpf_reader.h b/xcore/xcam_cpf_reader.h
new file mode 100644
index 0000000..cffb4e2
--- /dev/null
+++ b/xcore/xcam_cpf_reader.h
@@ -0,0 +1,79 @@
+/*
+ *  Copyright (c) 2014 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: Wind Yuan <feng.yuan@intel.com>
+ */
+
+/*
+ * \file xcam_cpf_reader.h
+ * \brief  xcam CPF reader
+*/
+
+#ifndef _XCAM_CPF_READER_H
+#define _XCAM_CPF_READER_H
+
+#include "xcam_defs.h"
+#include <stdint.h>
+#include <string.h>
+#include <stddef.h>
+
+XCAM_BEGIN_DECLARE
+
+
+typedef int boolean;
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+typedef struct _XCamCpfBlob XCamCpfBlob;
+
+/*! \brief CPF blob
+ */
+struct _XCamCpfBlob {
+    uint8_t *data; /*!< pointer to buffer*/
+    uint32_t size; /*!< buffer size*/
+};
+
+/*! \brief XCam CPF blob allocation.
+ *  buffer is initialized to zero
+ *
+ * \return    pointer to XCam CPF Blob
+ */
+XCamCpfBlob * xcam_cpf_blob_new ();
+
+/*! \brief XCam CPF blob release.
+ *  release the blob structure as well as the buffer inside it.
+ *
+ * \param[in,out]    pointer to XCam CPF Blob
+ */
+void xcam_cpf_blob_free (XCamCpfBlob *blob);
+
+/*! \brief XCam CPF blob release.
+ *  release the blob structure as well as the buffer inside it. Called in xcam_3a_init().
+ *
+ * \param[in]     cpf_file   CPF file name
+ * \param[out]    aiq_cpf    pointer to XCam CPF Blob which will hold AIQ records
+ * \param[out]    hal_cpf    pointer to XCam CPF HAL which will hold HAL records
+ */
+boolean xcam_cpf_read (const char *cpf_file, XCamCpfBlob *aiq_cpf, XCamCpfBlob *hal_cpf);
+
+XCAM_END_DECLARE
+
+#endif //_XCAM_CPF_READER_H
diff --git a/xcore/xcam_defs.h b/xcore/xcam_defs.h
new file mode 100644
index 0000000..519c1fa
--- /dev/null
+++ b/xcore/xcam_defs.h
@@ -0,0 +1,106 @@
+/*
+ * xcam_defs.h - macros defines
+ *
+ *  Copyright (c) 2014-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: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#ifndef XCAM_DEFS_H
+#define XCAM_DEFS_H
+
+#ifndef XCAM_LOG_ERROR
+#define XCAM_LOG_ERROR(format, ...)    \
+    printf ("XCAM ERROR %s:%d: " format "\n", __FILE__, __LINE__, ## __VA_ARGS__)
+#endif
+
+#ifndef XCAM_LOG_WARNING
+#define XCAM_LOG_WARNING(format, ...)   \
+    printf ("XCAM WARNING %s:%d: " format "\n", __FILE__, __LINE__, ## __VA_ARGS__)
+#endif
+
+#ifndef XCAM_LOG_INFO
+#define XCAM_LOG_INFO(format, ...)   \
+    printf ("XCAM INFO %s:%d: " format "\n", __FILE__, __LINE__, ## __VA_ARGS__)
+#endif
+
+#ifdef DEBUG
+#ifndef XCAM_LOG_DEBUG
+#define XCAM_LOG_DEBUG(format, ...)   \
+      printf ("XCAM DEBUG %s:%d: " format "\n", __FILE__, __LINE__, ## __VA_ARGS__)
+#endif
+#else
+#define XCAM_LOG_DEBUG(...)
+#endif
+
+#define XCAM_ASSERT(exp)  assert(exp)
+
+#ifdef  __cplusplus
+#define XCAM_BEGIN_DECLARE  extern "C" {
+#define XCAM_END_DECLARE    }
+#else
+#define XCAM_BEGIN_DECLARE
+#define XCAM_END_DECLARE
+#endif
+
+#ifndef __user
+#define __user
+#endif
+
+#define XCAM_UNUSED(variable) (void)(variable)
+
+#define XCAM_MAX(a, b)  ((a) > (b) ? (a) : (b))
+#define XCAM_MIN(a, b)  ((a) < (b) ? (a) : (b))
+
+#define XCAM_FAIL_RETURN(LEVEL, exp, ret, msg, ...)         \
+    if (!(exp)) {                                           \
+        XCAM_LOG_##LEVEL (msg, ## __VA_ARGS__);             \
+        return (ret);                                       \
+    }
+
+#define XCAM_DEAD_COPY(ClassObj)                \
+        ClassObj (const ClassObj&);             \
+        ClassObj & operator= (const ClassObj&)  \
+ 
+
+#define XCAM_STR(str)  ((str) ? (str) : "null")
+#define XCAM_BOOL2STR(value)  ((value) ? "true" : "false")
+
+#define XCAM_DOUBLE_EQUAL(a, b, tolerance)  \
+    (((a) >= ((b) - tolerance)) && ((a) <= ((b) + tolerance)))
+
+#define XCAM_DOUBLE_EQUAL_AROUND(a, b)  \
+    XCAM_DOUBLE_EQUAL(a, b, 0.000001)
+
+#define XCAM_GAMMA_TABLE_SIZE 256
+
+#define XCAM_TIMESPEC_2_USEC(timespec) ((timespec).tv_sec*1000000LL + (timespec).tv_nsec/1000)
+#define XCAM_TIMEVAL_2_USEC(timeval) ((timeval).tv_sec*1000000LL + (timeval).tv_usec)
+
+#define XCAM_TIMESTAMP_2_SECONDS(t) ((t)/1000000)
+#define XCAM_SECONDS_2_TIMESTAMP(t) ((t)*1000000)
+
+#define XCAM_TIMESTAMP_FORMAT "%02d:%02d:%02d.%03d"
+
+#define XCAM_TIMESTAMP_ARGS(t)                \
+    (int32_t)(XCAM_TIMESTAMP_2_SECONDS(t)/3600),       \
+    (int32_t)((XCAM_TIMESTAMP_2_SECONDS(t)%3600)/60),  \
+    (int32_t)(XCAM_TIMESTAMP_2_SECONDS(t)%60),         \
+    (int32_t)(((t)/1000)%1000)
+
+// align must be a interger of power 2
+#define XCAM_ALIGN_UP(value, align) (((value)+((align)-1))&(~((align)-1)))
+
+#endif //XCAM_DEFS_H
diff --git a/xcore/xcam_mutex.h b/xcore/xcam_mutex.h
new file mode 100644
index 0000000..bed8227
--- /dev/null
+++ b/xcore/xcam_mutex.h
@@ -0,0 +1,106 @@
+/*
+ * xcam_mutex.h - Lock
+ *
+ *  Copyright (c) 2014 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: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#ifndef XCAM_MUTEX_H
+#define XCAM_MUTEX_H
+
+#include <pthread.h>
+#include <sys/time.h>
+
+namespace XCam {
+
+class Mutex {
+    friend class Cond;
+private:
+    XCAM_DEAD_COPY (Mutex);
+
+public:
+    Mutex () {
+        pthread_mutex_init (&_mutex, NULL);
+    }
+    virtual ~Mutex () {
+        pthread_mutex_destroy (&_mutex);
+    }
+
+    void lock() {
+        pthread_mutex_lock (&_mutex);
+    }
+    void unlock() {
+        pthread_mutex_unlock (&_mutex);
+    }
+
+private:
+    pthread_mutex_t _mutex;
+};
+
+class Cond {
+private:
+    XCAM_DEAD_COPY (Cond);
+
+public:
+    Cond () {
+        pthread_cond_init (&_cond, NULL);
+    }
+    ~Cond () {
+        pthread_cond_destroy (&_cond);
+    }
+
+    int wait (Mutex &mutex) {
+        return pthread_cond_wait (&_cond, &mutex._mutex);
+    }
+    int timedwait (Mutex &mutex, uint32_t time_in_us) {
+        struct timeval now;
+        struct timespec abstime;
+
+        gettimeofday (&now, NULL);
+        now.tv_usec += time_in_us;
+        abstime.tv_sec += now.tv_sec + now.tv_usec / 1000000;
+        abstime.tv_nsec = (now.tv_usec % 1000000) * 1000;
+
+        return pthread_cond_timedwait (&_cond, &mutex._mutex, &abstime);
+    }
+
+    int signal() {
+        return pthread_cond_signal (&_cond);
+    }
+    int broadcast() {
+        return pthread_cond_broadcast (&_cond);
+    }
+private:
+    pthread_cond_t _cond;
+};
+
+class SmartLock {
+private:
+    XCAM_DEAD_COPY (SmartLock);
+
+public:
+    SmartLock (XCam::Mutex &mutex): _mutex(mutex) {
+        _mutex.lock();
+    }
+    virtual ~SmartLock () {
+        _mutex.unlock();
+    }
+private:
+    XCam::Mutex &_mutex;
+};
+};
+#endif //XCAM_MUTEX_H
+
diff --git a/xcore/xcam_thread.cpp b/xcore/xcam_thread.cpp
new file mode 100644
index 0000000..8daa41e
--- /dev/null
+++ b/xcore/xcam_thread.cpp
@@ -0,0 +1,115 @@
+/*
+ * xcam_thread.cpp - Thread
+ *
+ *  Copyright (c) 2014 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: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#include "xcam_thread.h"
+#include "xcam_mutex.h"
+
+namespace XCam {
+
+Thread::Thread (const char *name)
+    : _name (NULL)
+    , _thread_id (0)
+    , _started (false)
+{
+    if (name)
+        _name = strdup (name);
+}
+
+Thread::~Thread ()
+{
+    if (_name)
+        xcam_free (_name);
+}
+
+int
+Thread::thread_func (void *user_data)
+{
+    Thread *thread = (Thread *)user_data;
+    bool ret = true;
+
+    {
+        // Make sure running after start
+        SmartLock locker(thread->_mutex);
+        pthread_detach (pthread_self());
+    }
+    ret = thread->started ();
+
+    while (true) {
+        {
+            SmartLock locker(thread->_mutex);
+            if (!thread->_started || ret == false) {
+                thread->_started = false;
+                thread->_thread_id = 0;
+                thread->_exit_cond.signal();
+                ret = false;
+                break;
+            }
+        }
+
+        ret = thread->loop ();
+    }
+
+    thread->stopped ();
+
+    return 0;
+}
+
+bool
+Thread::started ()
+{
+    XCAM_LOG_DEBUG ("Thread(%s) started", XCAM_STR(_name));
+    return true;
+}
+
+void
+Thread::stopped ()
+{
+    XCAM_LOG_DEBUG ("Thread(%s) stopped", XCAM_STR(_name));
+}
+
+bool Thread::start ()
+{
+    SmartLock locker(_mutex);
+    if (_started)
+        return true;
+
+    if (pthread_create (&_thread_id, NULL, (void * (*)(void*))thread_func, this) != 0)
+        return false;
+    _started = true;
+    return true;
+}
+
+bool Thread::stop ()
+{
+    SmartLock locker(_mutex);
+    if (_started) {
+        _started = false;
+        _exit_cond.wait(_mutex);
+    }
+    return true;
+}
+
+bool Thread::is_running ()
+{
+    SmartLock locker(_mutex);
+    return _started;
+}
+
+};
diff --git a/xcore/xcam_thread.h b/xcore/xcam_thread.h
new file mode 100644
index 0000000..248d883
--- /dev/null
+++ b/xcore/xcam_thread.h
@@ -0,0 +1,63 @@
+/*
+ * xcam_thread.h - Thread
+ *
+ *  Copyright (c) 2014 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: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#ifndef XCAM_THREAD_H
+#define XCAM_THREAD_H
+
+#include <pthread.h>
+#include "xcam_defs.h"
+#include "xcam_common.h"
+#include "xcam_mutex.h"
+
+namespace XCam {
+
+class Thread {
+public:
+    Thread (const char *name = NULL);
+    virtual ~Thread ();
+
+    bool start ();
+    bool stop ();
+    bool is_running ();
+
+protected:
+    // return true to start loop, else the thread stopped
+    virtual bool started ();
+    virtual void stopped ();
+    // return true to continue; false to stop
+    virtual bool loop () = 0;
+private:
+    XCAM_DEAD_COPY (Thread);
+
+
+private:
+    static int thread_func (void *user_data);
+
+private:
+    char           *_name;
+    pthread_t       _thread_id;
+    XCam::Mutex     _mutex;
+    XCam::Cond      _exit_cond;
+    bool            _started;
+};
+
+};
+
+#endif //XCAM_THREAD_H
diff --git a/xcore/xcam_utils.h b/xcore/xcam_utils.h
new file mode 100644
index 0000000..c44f621
--- /dev/null
+++ b/xcore/xcam_utils.h
@@ -0,0 +1,31 @@
+/*
+ * xcam_utils.h - xcam utilities
+ *
+ *  Copyright (c) 2014-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: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#ifndef XCAM_UTILS_H
+#define XCAM_UTILS_H
+
+#include "xcam_common.h"
+
+namespace XCam {
+
+static const int64_t InvalidTimestamp = INT64_C(-1);
+};
+
+#endif //XCAM_UTILS_H